【问题标题】:Get value from graphicView.bidvalue从 graphicsView.bidvalue 中获取价值
【发布时间】:2020-11-07 20:20:15
【问题描述】:

我需要使用 Python 中的 Beautiful Soup 从这段代码中获取 5,2329 的值。我应该怎么做才能正确地做到这一点?

<span class="chart-info-val ng-binding" ng-bind="graphicView.bidvalue">5,2329</span>

我的代码是:

    def info(link):
    html = urlopen(link)
    res = BeautifulSoup(html.read(), "html.parser")
    main = res.findAll("div",{"class":"info-content"})
    tag = main[0]
    cotacao = tag.select('span.chart-info-val ng-binding')
    print(cotacao)


info("https://economia.uol.com.br/cotacoes/bolsas/acoes/bvsp-bovespa/wege3-sa")

ps:

【问题讨论】:

  • 看起来你的代码没有通过

标签: python css web web-scraping beautifulsoup


【解决方案1】:

没有代码,所以我只能假设某些事情。

代码示例

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 生成的网站。

附加信息

一般来说动态抓取数据有三种方式。

  1. 对 HTTP 请求进行逆向工程。

那是因为 javascript 正在调用服务器,如果我们能够模仿这些请求应该能够获得我们想要的数据。这种方法的优点是快速高效。与其他方法不同。这通常只需要发出一个简单的 HTTP get/post 请求,但也可能需要添加标头、cookie 和参数等内容。

  1. 使用 splash 预渲染页面

Splash 框架可以预渲染页面,即捕获文档 DOM 并允许您选择所有页面。它不如逆向工程 HTTP 请求高效,但它是相对轻量级的方法

  1. 呈现页面并使用浏览器活动。

您可以使用 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

通过一些工作,您可以非常高效地获取数据。

【讨论】:

  • 我用我正在使用的代码编辑了帖子,我用你的方法,输出仍然是“[]”
  • 您能否向我们提供您正在使用的全部代码?例如,我看不到 URL。我的回答是基于对应该发生什么的假设。由于动态内容,页面可能无法被beautifulsoup解析。
  • 网址是“economia.uol.com.br/cotacoes/bolsas/acoes/bvsp-bovespa/wege3-sa”,我想得到那个 58,09
  • 动态生成的 span 元素。那就是网站中的javascript正在生成数据。您将需要能够动态地获取这些数据。在网站上,您可以通过对 HTTP 请求进行逆向工程来做到这一点。
  • 这有多难?
猜你喜欢
  • 2013-04-11
  • 2018-09-14
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多