【问题标题】:Extracting text from a span with lxml?使用lxml从跨度中提取文本?
【发布时间】:2015-10-05 18:42:29
【问题描述】:

给定:

import urllib2
from lxml import etree

url =  "http://www.ebay.com/sch/i.html?rt=nc&LH_Complete=1&_nkw=Under+Armour+Dauntless+Backpack&LH_Sold=1&_sacat=0&LH_BIN=1&_from=R40&_sop=3&LH_ItemCondition=1000"
response = urllib2.urlopen(url)
htmlparser = etree.HTMLParser()
tree = etree.parse(response, htmlparser)

URL 是一个标准的 Ebay 搜索结果页面,应用了一些过滤:

我希望提取产品价格,例如40.00 美元、34.95 美元等。

有几种可能的 XPath(由 Firebug、XPath Checker Firefox 插件和手动检查源提供):

/html/body/div[5]/div[2]/div[3]/div/div[1]/div/div[3]/div/div[1]/div/w-root/div/div/ul/li[1]/ul[1]/li[1]/span
id('item3d00cf865e')/x:ul[1]/x:li[1]/x:span
//span[@class ='bold bidsold']

选择后者:

xpathselector="//span[@class ='bold bidsold']"

tree.xpath(xpathselector) 然后按预期返回Element 对象列表。当我得到他们的.text 属性时,我会期望得到价格。但我得到的是:

In [17]: tree.xpath(xpathselector)
Out[17]: 
['\n\t\t\t\t\t',
 u' 1\xc2\xa0103.78',
 '\n\t\t\t\t\t',
 u' 1\xc2\xa0048.28',
 '\n\t\t\t\t\t',
 ' 964.43',
 '\n\t\t\t\t\t',
 ' 922.43',
 '\n\t\t\t\t\t',
 ' 922.43',
 '\n\t\t\t\t\t',
 ' 275.67',
 '\n\t\t\t\t\t',

每个值中包含的值看起来像价格,但是 (i) 价格远高于网页上显示的价格,(ii) 我想知道所有换行符和制表符都在那里做什么。 我在试图提取价格时有什么根本错误吗?

我通常将 WebDriver 用于此类事情,并利用 css 选择器、xpath 和类查找元素。但在这种情况下,我不希望与浏览器交互,这就是我第一次使用urllib2lxml 的原因。

等等

【问题讨论】:

    标签: python python-2.7 xpath lxml


    【解决方案1】:

    我在python上写了两个例子

    示例 1:

    import urllib2
    from lxml import etree
    
    if __name__ == '__main__':
        url =  "http://www.ebay.com/sch/i.html?rt=nc&LH_Complete=1&_nkw=Under+Armour+Dauntless+Backpack&LH_Sold=1&_sacat=0&LH_BIN=1&_from=R40&_sop=3&LH_ItemCondition=1000"
        response = urllib2.urlopen(url)
        htmlparser = etree.HTMLParser()
        tree = etree.parse(response, htmlparser)
        xpathselector="//span[@class ='bold bidsold']"
        for i in tree.xpath(xpathselector):
            print "".join(filter(lambda x: ord(x)<64, i.text)).strip()
    

    示例 2:

    import urllib2
    from lxml import etree
    
    if __name__ == '__main__':
        url =  "http://www.ebay.com/sch/i.html?rt=nc&LH_Complete=1&_nkw=Under+Armour+Dauntless+Backpack&LH_Sold=1&_sacat=0&LH_BIN=1&_from=R40&_sop=3&LH_ItemCondition=1000"
        response = urllib2.urlopen(url)
        htmlparser = etree.HTMLParser()
        tree = etree.parse(response, htmlparser)
        xpathselector="//span[@class ='bold bidsold']|//span[@class='sboffer']"
        for i in tree.xpath(xpathselector):
            print "".join(filter(lambda x: ord(x)<64, i.text)).strip()
    

    【讨论】:

      【解决方案2】:

      我看到两种可能的情况:

      1. 看起来 ebay 会检查您的语言环境并根据您所在国家/地区的货币转换价格。一旦你通过浏览器打开页面,它可能会读取一些浏览器设置,一旦你执行代码,它就可以从其他地方读取设置。
      2. ebay 可能会使用 javascript(客户端)调整价格,因此您无法使用解析器进行调整。

      我建议检查下一个:

      1. 在运行代码时检查您拥有的货币
      2. 检查页面来源并确认那里的价格与您在浏览器中看到的完全一样。

      【讨论】:

      • 谢谢,是的,经过仔细检查,我发现它既是 (i) 转换货币,也是 (ii) 将页面返回到西班牙语的 urllib2。 urllib2 中有没有办法欺骗位置?
      • @Pyderman 尝试检查您的请求到底是什么样的。找一个工具,你可能会找到一些关于语言环境的信息。
      猜你喜欢
      • 1970-01-01
      • 2016-02-07
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      • 2013-08-25
      • 1970-01-01
      • 2016-05-11
      • 1970-01-01
      相关资源
      最近更新 更多