没有代码,所以我只能假设某些事情。
代码示例
soup = BeautifulSoup(html.text, 'html.parser')
data = soup.select('span.chart-info-val ng-binding').get_text()
解释
select方法使用CSS选择器抓取beautifulsoup解析过的HTML。
soup.select('span.chart-info-val ng-binding').get_text()
上面的例子
-
span: 抓取任意 span 标签
-
. : 在这里表示 CSS 中的一个类,该类是 chart-info-val ng-binding
-
get_text():使用 class chart-info-val ng-binding 从 span 中获取文本
找到网址后,我知道您为什么无法抓取内容。正如我所解释的,浏览器以三种主要方式加载信息。 HTML、CSS 和 JavaScript。 HTML 严格用于文本和标记页面,CSS 用于样式和 Javascript 可以做各种各样的事情,包括生成数据。这里每次刷新页面,网站都会调用服务器来获取股价数据,然后显示出来。它没有硬编码到 HTML 中,而是嵌入了 javascript。
如果没有一些帮助,BeautifulSoup 无法处理 javascript 生成的网站。
附加信息
一般来说动态抓取数据有三种方式。
- 对 HTTP 请求进行逆向工程。
那是因为 javascript 正在调用服务器,如果我们能够模仿这些请求应该能够获得我们想要的数据。这种方法的优点是快速高效。与其他方法不同。这通常只需要发出一个简单的 HTTP get/post 请求,但也可能需要添加标头、cookie 和参数等内容。
- 使用 splash 预渲染页面
Splash 框架可以预渲染页面,即捕获文档 DOM 并允许您选择所有页面。它不如逆向工程 HTTP 请求高效,但它是相对轻量级的方法
- 呈现页面并使用浏览器活动。
您可以使用 selenium 包来模拟浏览器活动,欺骗您正在使用浏览器的网站。它是重量级的,而且该框架从未真正用于网络抓取,而是用于自动化测试。本质上,selenium webdriver 提供了一个 HTTP 服务器,一个与浏览器的安全连接。然后,我们可以通过向该服务器发送 HTTP 请求来执行任何浏览器活动,并将 webdriver 定向到特殊类型的浏览器以进行自动化测试。根据您的数据需求,这会成为一种缓慢的方法。
代码更新
话虽如此,您想要数据的网站实际上很容易获得您想要的信息。我们可以通过对 HTTP 请求进行逆向工程来做到这一点。本质上,该网站正在向服务器发出 HTTP 获取请求,然后响应显示股票价格。
要了解网站是如何执行此操作的,我们必须能够检查请求。使用 chrometools 这很容易。如果您加载页面,右键单击检查,您将获得一个带有 HTML 代码的窗口。如果您单击网络选项卡,您可以看到所有请求的列表。
这里有一些图片可以指导您浏览 HTTP 请求。我们本质上是在记录浏览器活动。在 XHR 中,即 XMLHttpRequest,它指的是 javascript 为获取数据而生成的请求,这是可以找到数据的地方。我们点击请求并点击预览,直到我们从请求中看到我们想要的数据。然后我们右键单击并复制 CURL BASH 命令并将其粘贴到 curl.trillworks.com 之类的网站中。在这里我们可以将请求转换成python。这为我们提供了格式良好的 headers/params/cookies 以使请求看起来真实。
图片:
Here
Here
所以现在我们有了发出请求的正确 URL,以及任何标头。首先,值得在服务器上尝试请求获取方法。如果你很幸运,你不需要包含标题/参数。对此进行测试,您唯一需要做的就是使用参数并发出 get 请求,不需要标头。
这是 HTTP 请求的详细信息。
url = 'https://api.cotacoes.uol.com/asset/intraday/list/'
params = (('format', 'JSON'),
('fields', 'price,high,low,open,volume,close,bid,ask,change,pctChange,date'),
('item', '704'),
('', ''),)
headers = {
'Accept': 'application/json, text/plain, */*',
'Referer': 'https://economia.uol.com.br/cotacoes/bolsas/acoes/bvsp-bovespa/wege3-sa',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',}
这样,您可以使用下面的代码进行一些测试。事实证明,您不需要这些标头,它只需要参数。
编码示例
import requests
params = (
('format', 'JSON'),
('fields', 'price,high,low,open,volume,close,bid,ask,change,pctChange,date'),
('item', '704'),
('', ''),)
response = requests.get('https://api.cotacoes.uol.com/asset/intraday/list/', params=params)
data = response.json()
输出
{'prev': None,
'next': None,
'docs': [{'price': 58.09,
'high': 58.46,
'low': 54.7,
'open': 55.03,
'volume': 6435500,
'close': 54.55,
'bid': 58.09,
'ask': 58.11,
'change': 3.54,
'pctChange': 6.49,
解释
我们从 curl.trillworks.com 获取参数,并使用我们在图像中找到的 URL 使用这些特定参数发出获取请求。我们得到的响应称为 JSON 对象。 response.json() 方法将此 JSON 对象转换为可操作的 python 字典。在这里您可以看到带有所需数据的输出。
要获得您想要的数据,我们已经通过这本字典。您可以在字典的 docs 部分看到所需的数据。
data = response.json()['docs']
输出:
[{'price': 58.09,
'high': 58.46,
'low': 54.7,
'open': 55.03,
'volume': 6435500,
'close': 54.55,
'bid': 58.09,
'ask': 58.11,
'change': 3.54,
'pctChange': 6.49,
'date': '20200717170900'},
现在我们可以看到价格嵌套在一个列表中。
data = response.json()['docs'][0]['price']
输出
58.09
通过一些工作,您可以非常高效地获取数据。