【问题标题】:scraping dynamic updates of temperature sensor data from a website从网站上抓取温度传感器数据的动态更新
【发布时间】:2015-08-15 20:01:14
【问题描述】:

我写了以下python代码:

from bs4 import BeautifulSoup
import urllib2

url= 'http://www.example.com'
page = urllib2.urlopen(url)
soup = BeautifulSoup(page.read(),"html.parser")
freq=soup.find('div', attrs={'id':'frequenz'})
print freq

结果是:

<div id="frequenz" style="font-size:500%; font-weight: bold; width: 100%; height: 10%; margin-top: 5px; text-align: center">tempsensor</div>

当我使用网络浏览器查看此站点时,网页显示的是动态内容,而不是字符串“tempsensor”。温度值每秒自动刷新一次。所以网页中的内容是 自动将字符串“tempsensor”替换为数值。

我现在的问题是:如何让 Python 显示更新后的数值? BeautifulSoup中如何获取自动更新到tempsensor的值?

【问题讨论】:

  • "如何通过 python 评估变量 tempsensor 的值?" - 我没有看到任何变量...
  • 实际网址是什么?
  • 啊,我明白了。 JavaScript 正在更新您想要的值。您不能只为它解析 HTML。您需要弄清楚 API。
  • 看起来你只是请求http://www.netzfrequenz.info/json/aktuell2.json?_=&lt;unix_time_in_milliseconds&gt;。例如,netzfrequenz.info/json/aktuell2.json?_=1439677724960

标签: python html url scrape


【解决方案1】:

抱歉,不,仅靠 BeautifulSoup 是不可能的。

问题在于 BS4 不是一个完整的网络浏览器。它只是一个 HTML 解析器。它不解析 CSS,也不解析 Javascript。

一个完整的网络浏览器至少做四件事:

  1. 连接到网络服务器,获取数据
  2. 解析 HTML 内容和 CSS 格式并呈现网页
  3. 解析 Javascript 内容,运行它。
  4. 为浏览器导航、HTML 表单和 Javascript 程序的事件 API 等内容提供用户交互

还不确定?现在看看你的代码。 BS4 甚至不包括第一步,获取网页,你必须使用urllib2

动态网站通常包含在浏览器上运行并定期更新内容的 Javascript。 BS4 不提供,因此您不会看到它们,而且仅使用 BS4 也永远不会。为什么?由于上述第 (3) 项,没有发生下载和执行 Javascript 程序。它会在 IE、Firefox 或 Chrome 中发生,这就是为什么它们可以显示动态内容,而仅 BS4 的抓取不显示它。

PhantomJSCasperJS 提供了一种更加机械化的浏览器,通常可以运行 JavaScript 代码来启用动态网站。但是 CasperJS 和 PhantomJS 是用服务器端 Javascript 编程的,而不是 Python。

显然,有些人是 using a browser built into PyQt4 for these kinds of dynamic screenscaping tasks,隔离了部分 DOM,并将其发送到 BS4 进行解析。这可能允许使用 Python 解决方案。

在 cmets 中,@Cyphase 建议您想要的确切数据可能在不同的 URL 中可用,在这种情况下,可能会使用 urllib2/BS4 获取和解析它。这可以通过仔细检查站点上运行的 Javascript 来确定,特别是您可以查找用于安排更新的 setTimeoutsetInterval,或用于从后面获取数据的 ajax,或 jQuery 的 .load 函数结尾。用于更新动态内容的 Javascript通常只会从同一网站的后端 URL 获取数据。如果他们使用 jQuery $('#frequenz') 指的是 div,并且通过在 JS 中搜索它,您可能会找到更新 div 的代码。如果没有 jQuery,JS 更新可能会使用 document.getElementById('frequenz')

【讨论】:

    【解决方案2】:

    你遗漏了一点代码:

    from bs4 import BeautifulSoup
    import urllib2
    
    url= 'http://www.example.com'
    page = urllib2.urlopen(url)
    soup = BeautifulSoup(page.read(), 'html.parser')
    freq = soup.find('div', attrs={'id':'frequenz'})
    print freq.string  # Added .string
    

    【讨论】:

    • freq.string 只给我变量的字符串(名称)而不是值。在这种情况下,它是每秒更新的温度值。 tempsensor 只是变量名。
    • 啊,我以为你的问题措辞很奇怪。但是你在说什么价值?我在任何地方都看不到价值。
    • 哦,你的意思是你的程序中有一个变量叫tempsensor?如果是这样,你能把它放在dict 中吗?如果是这样,您可以使用print variable_dict[freq.string]。让我知道这是否适合您;如果有,我会更新答案。
    • 是的 html 代码包含这个变量,我想在 python 中获取值。
    • @ChrisWeber,&lt;div id="frequenz" style="font-size:500%; font-weight: bold; width: 100%; height: 10%; margin-top: 5px; text-align: center"&gt;tempsensor&lt;/div&gt; 中的值在哪里?
    【解决方案3】:

    应该这样做:

    freq.text.strip()
    

    >>> html = '<div id="frequenz" style="font-size:500%; font-weight: bold; width: 100%; height: 10%; margin-top: 5px; text-align: center">tempsensor</div>'
    >>> soup = BeautifulSoup(html)
    >>> soup.text.strip()
    u'tempsensor'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 1970-01-01
      • 2013-03-14
      相关资源
      最近更新 更多