【问题标题】:lxml tree head and some other elements brokenlxml 树头和其他一些元素损坏
【发布时间】:2014-05-27 18:28:39
【问题描述】:

针对以下问题,我尝试了许多不同的解决方案,但目前找不到一个可行的解决方案。 我需要从几个网页的元标记中获取一些信息。为此,我发现 lxml 非常有用,因为我还需要使用 xpath 查找特定内容来解析它。 XPath 在树上工作,但是,我有 20% 的网站(总共大约 100 个)不起作用,特别是头部似乎坏了。

tree = html.fromstring(htmlfrompage)  // using html from lxml package
head_object = tree.head               // access to head object from this webpage

在所有这些网站中,访问 head 对象(这只是 xpath 的快捷方式)都失败并出现相同的错误:

print tree.head
IndexError: list index out of range

因为下面的 xpath 失败了:

self.xpath('//head|//x:head', namespaces={'x':XHTML_NAMESPACE})[0]

此 xpath 为空,因此访问第一个元素失败。我自己在树中导航,而 self.xpath('//head') 或 self.xpath('//html/head') 甚至 self.xpath('//body') 都是空的。但是,如果我尝试直接在文档的任何位置访问元标记:

head = tree.xpath("//meta")
for meta_tag in head:
    print meta_tag.text  # Just printing something

它有效,所以这意味着元数据以某种方式没有连接到头部,但它们漂浮在树的某个地方。反正头也不存在。当然,我可以尝试“修补”这个访问 head 的问题,如果我得到一个超出范围异常的索引,我可以导航 metas 以找到我正在寻找的内容,但我希望 lxml 修复损坏的 html(正如我在文档中阅读的那样)。

有没有人遇到过同样的问题并能以更好的方式解决它?

【问题讨论】:

  • 你能给我们一个这样的网站的例子,以便我们重现并提出解决方案吗?
  • 当然,这是一个例子。 lanacion.com.ar/…
  • 看起来您的本地 LXML 设置是 b0rken。该链接对我来说很好。这可能是由于您系统上的libxml2 版本过时。
  • 所以如果你得到 tree.head 它可以工作吗?我要检查我的 lib 版本
  • 是的,我收到了tree.head 的那个文档,没问题。

标签: python web-scraping lxml


【解决方案1】:

使用requests 我可以很好地加载树:

>>> import requests
>>> from lxml import html
>>> r = requests.get('http://www.lanacion.com.ar/1694725-ciccone-manana-debera-declarar-carosso-donatiello-el-inquilino-de-boudou')
>>> tree = html.fromstring(r.content)
>>> tree.head
<Element head at 0x10681b4c8>

请注意,您要将 字节字符串 传递给html.fromstring();不要使用r.text,因为它会传入 Unicode。

此外,如果服务器未在标头中指明编码,requests 将回退到 HTTP RFC 默认值,即 ISO-8859-1 用于text/ 响应。对于这个不正确的特定响应:

>>> r.headers['Content-Type']
'text/html'
>>> r.encoding
'ISO-8859-1'
>>> r.apparent_encoding  # make an educated guess
'utf-8'

这意味着r.text 将使用 Latin-1 来解码 UTF-8 数据,导致解码错误的 Unicode 字符串,进一步混淆问题。

另一方面,HTML 解析器可以利用 &lt;meta&gt; 标头来告诉它使用什么编码:

>>> tree.find('.//meta').attrib
{'content': 'text/html; charset=utf-8', 'http-equiv': 'Content-Type'}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多