【问题标题】:Can't extract a value out of HTML with lxml无法使用 lxml 从 HTML 中提取值
【发布时间】:2016-05-16 00:08:05
【问题描述】:

我有这段 HTML(数字不同):

<span class="ng-binding"> <b>Total:</b> 68.71€ (459 items) </span>


我想从中提取68.71€ (459 items)


到目前为止,我尝试使用这段代码进行此操作,只是将 xpath 从 Google Chrome 复制到上面显示的 span 类:

import urllib.request
from lxml import html
import os

ids =  ["ftpstorage1-730",
        "ftpstorage2-730",
        "ftpstorage3-730"]

for id in ids:

url = 'http://steam.tools/itemvalue/#/'+id
with urllib.request.urlopen(url) as response:
    site = response.read()
    tree = html.fromstring(site)
    data = tree.xpath('//*[@id="container"]/div[5]/span[1]/text()')

    print(data)

理论上这应该有效,但它不会,我得到的只是data 是:

[" {{(items | filter:dupesFilter | filter:typeFilter | filter:filterText |   sumByKey:'price':'count':
e}}\n\t\t\t\t({{items | filter:dupesFilter | filter:typeFilter |    filter:filterText | sumByKey:'count
[" {{(items | filter:dupesFilter | filter:typeFilter | filter:filterText | sumByKey:'price':'count':
e}}\n\t\t\t\t({{items | filter:dupesFilter | filter:typeFilter | filter:filterText | sumByKey:'count
[" {{(items | filter:dupesFilter | filter:typeFilter | filter:filterText | sumByKey:'price':'count':
e}}\n\t\t\t\t({{items | filter:dupesFilter | filter:typeFilter | filter:filterText | sumByKey:'count

知道我做错了什么吗?

这与生成的数字不是静态的有关吗?

如果是这样,我怎样才能提取数字?

【问题讨论】:

  • 数据不在源中,是动态生成的
  • @PadraicCunningham 奖励积分如果您通过requests 获得总数。 :)
  • @alecxe,你打败了我!
  • @PadraicCunningham 抱歉,一开始我想到了硒,但后来我意识到我可以在这里打败你:)
  • @PadraicCunningham 好的,谢谢,但我需要喝点烈性酒才能接近那个人。

标签: python python-3.x xpath lxml


【解决方案1】:

您在控制台上看到的是 带有 AngularJS 绑定占位符的未渲染 HTML。您需要一个真正的浏览器来执行 javascript 并让 Angular 将真正的值放入占位符中。

或者,如果您深入了解如何检索和计算总价,则无需使用真正的浏览器即可解决此问题。向提供idapp 参数的http://item-value10.appspot.com/ParseInv 端点发出GET 请求,解析JSON 响应并根据商品数量计算价格:

import requests


template_url = "http://item-value10.appspot.com/ParseInv"
ids = ["ftpstorage1-730", "ftpstorage2-730", "ftpstorage3-730"]

for id in ids:
    with requests.Session() as session:
        session.get('http://steam.tools/itemvalue/#/' + id)

        storage, app = id.split("-")
        url = template_url.format(storage=storage, app=app)

        response = session.get(url, params={
            "id": storage,
            "app": app
        }, headers={
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36",
            "Referer": "http://steam.tools/itemvalue/"
        })

        data = response.json()
        total = sum(float(item["price"]) * int(item["count"]) for item in data["items"])
        print(total)

打印:

20.439999999999998
78.16
0

【讨论】:

  • @alecxe 天哪,那是一个漂亮的遮阳篷,非常感谢,正是我想要的,我也理解它背后的想法。
  • @alexce 我有一个简单的后续问题,我只是注意到这些数字是美元而不是欧元,我必须手动转换它们还是有办法让它们请求?
  • @Lyux 您应该向cdn.steam.tools/data/currency.json 提出请求并获取转换系数,然后相应地调整价格。谢谢。
猜你喜欢
  • 2015-01-20
  • 2013-08-25
  • 2015-10-06
  • 2016-05-11
  • 1970-01-01
  • 2018-03-20
  • 2015-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多