【问题标题】:lxml can't parse <table>?lxml 无法解析 <table>?
【发布时间】:2010-11-04 03:45:19
【问题描述】:

我想解析html中的表格,但是我发现lxml无法解析?怎么了?

# -*- coding: utf8 -*-
import urllib
import lxml.etree
keyword = 'lxml+tutorial'

url = 'http://www.baidu.com/s?wd='
if __name__ == '__main__':
    page = 0

    link = url + keyword + '&pn=' + str(page)

    f = urllib.urlopen(link)
    content = f.read()
    f.close()

    tree = lxml.etree.HTML(content)

    query_link = '//table'

    info_link = tree.xpath(query_link)

    print info_link

打印结果只是 []...

【问题讨论】:

标签: python parsing lxml web-crawler


【解决方案1】:

lxml 的documentation says, "对解析损坏的 HTML 的支持完全依赖于 libxml2 的恢复算法。如果您发现文档严重损坏以至于解析器无法处理它们,这不是 lxml 的错。也不能保证结果树将包含原始文档中的所有数据。解析器在努力继续解析时可能不得不丢弃严重损坏的部分。”

果然,百度返回的 HTML 是无效的:W3C validator reports "173 Errors, 7 warnings"。我不知道(也没有调查过)这些特定错误是否导致您在使用 lxml 时遇到麻烦,因为我认为您使用 lxml 解析“在野外”(几乎总是无效)发现的 HTML 的策略注定要失败.

为了解析无效的 HTML,您需要一个实现 (surprisingly bizarre!) HTML 错误恢复算法的解析器。所以我建议把lxml换成html5lib,它可以毫无问题地处理百度的无效HTML:

>>> import urllib
>>> from html5lib import html5parser, treebuilders
>>> p = html5parser.HTMLParser(tree = treebuilders.getTreeBuilder('dom'))
>>> dom = p.parse(urllib.urlopen('http://www.baidu.com/s?wd=foo').read())
>>> len(dom.getElementsByTagName('table'))
12

【讨论】:

  • 我记得,lxml 有 BeautifulSoup 和 html5lib 的钩子,所以有必要完全放弃它。 (我还没有需要它们所以我忘了)
【解决方案2】:

我看到有几个地方可以改进代码,但对于您的问题,以下是我的建议:

  1. 使用lxml.html.parse(link) 而不是lxml.etree.HTML(content),这样所有“正常工作”的自动功能都可以发挥作用。(例如,正确处理标题中的字符编码声明)

  2. 尝试使用tree.findall(".//table") 而不是tree.xpath("//table")。我不确定它是否会有所作为,但我只是在几个小时前在我自己的项目中使用了该语法而没有问题,并且作为奖励,它与非 LXML ElementTree API 兼容。

我建议的另一件主要事情是使用 Python 的内置函数来构建 URL,这样您就可以确保所构建的 URL 在任何情况下都是有效的并且正确转义。

如果 LXML 找不到表而浏览器显示表存在,我只能想象这是以下三个问题之一:

  1. 错误请求。 LXML 得到一个没有表格的页面。 (例如错误 404 或 500)
  2. 解析错误。直接调用时页面的某些内容使 lxml.etree.HTML 感到困惑。
  3. 需要Javascript。也许表格是在客户端生成的。

【讨论】:

  • 奇怪。我不知道从那里去哪里。我必须开始做一些测试,我已经准备睡觉了。
猜你喜欢
  • 2018-09-12
  • 2013-10-01
  • 2012-07-12
  • 2014-11-15
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 2012-06-10
  • 1970-01-01
相关资源
最近更新 更多