【问题标题】:Python 3.4 : LXML web scrapingPython 3.4:LXML 网页抓取
【发布时间】:2015-06-09 15:13:42
【问题描述】:

我正在使用以下代码尝试返回该网站上的代码列表。代码的结果是一个空列表。我从 google chromium 开发者工具中复制了 xpath。我究竟做错了什么?

from lxml import html
import requests


url = 'http://en.wikipedia.org/wiki/List_of_S%26P_500_companies'

resp = requests.get(url)
tree = html.fromstring(resp.text)

tickers = tree.xpath(r'//*[@id="mw-content-text"]/table[1]/tbody/tr[1]/td[1]/a')

print(tickers)

【问题讨论】:

    标签: python lxml


    【解决方案1】:

    浏览器会添加缺失的 HTML 元素,HTML 规范指出这些元素是模型的一部分。 lxml 不添加那些。

    最常见的此类元素是<tbody> 元素。你的文档没有这样的元素,但 Chrome 有,他们把它放在你的 XPath 中。 <thead> 元素中的另一个这样的元素;同样,原始的 HTML 缺少它,但 Chrome 将其放入并放入带有 <th> 元素的 <tr> 行。

    因此正确的 XPath 表达式是:

    tickers = tree.xpath(r'//*[@id="mw-content-text"]/table[1]/tr[2]/td[1]/a')
    

    例如表格中的第二行,该行中的第一个表格单元格。

    注意lxml可以直接加载URL;在这种特定情况下,您实际上不需要使用 requests

    >>> from lxml import html
    >>> url = 'http://en.wikipedia.org/wiki/List_of_S%26P_500_companies'
    >>> tree = html.parse(url)
    >>> tree.xpath(r'//*[@id="mw-content-text"]/table[1]/tr[2]/td[1]/a')
    [<Element a at 0x10445e628>]
    >>> tree.xpath(r'//*[@id="mw-content-text"]/table[1]/tr[2]/td[1]/a')[0].text
    'MMM'
    >>> tree.xpath(r'//*[@id="mw-content-text"]/table[1]/tr[2]/td[1]/a')[0].attrib['href']
    'https://www.nyse.com/quote/XNYS:MMM'
    

    如果您想提取第一列中的所有&lt;a&gt; 元素,则必须取消对&lt;tr&gt; 元素的限制;您的 XPath 选择所有,删除 [1] 以选择 all

    links = tree.xpath(r'//*[@id="mw-content-text"]/table[1]/tr/td[1]/a')
    for link in links:
        print(link.text, link.attrib['href'])
    

    【讨论】:

    • 现在如果我想要完整的代码列表怎么办? sp500 的每个组成部分都有多个 tr 和相应的 td 标签。
    • @AranFreel:只需删除 tr 选择器上的 [1] 限制即可。
    • 如果我想使用 lxml 打印整个表格怎么办...我最多可以打印第三个 td 标签,但之后它什么也不返回
    • @AranFreel:考虑到只有第 1、2、3 和 6 列有 &lt;a&gt; 链接标签。
    • 那是有道理的:-)
    猜你喜欢
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 2022-01-27
    • 1970-01-01
    相关资源
    最近更新 更多