我想在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
打印结果只是[] ......
答案 0 :(得分:3)
lxml的documentation says,“解析破坏的HTML的支持完全取决于libxml2的恢复算法。如果您发现文档严重破坏而解析器无法处理它们,则不是lxml的错误。还有不能保证生成的树将包含原始文档中的所有数据。解析器在努力保持解析时可能不得不丢弃严重损坏的部分。“
果然,百度返回的HTML无效:W3C validator reports“173错误,7个警告”。我不知道(并且没有调查过)这些特定的错误是否会给你的lxml带来麻烦,因为我认为你使用lxml解析HTML“在野外”(几乎总是无效的)的策略注定要失败
要解析无效的HTML,您需要一个实现(surprisingly bizarre!)HTML错误恢复算法的解析器。因此,我建议为html5lib交换lxml,它可以毫无问题地处理百度的无效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
答案 1 :(得分:2)
我看到几个代码可以改进的地方但是,对于你的问题,这是我的建议:
使用lxml.html.parse(link)
而不是lxml.etree.HTML(content)
,这样所有“正常工作”的自动装置都可以启动。(例如,正确处理标题中的字符编码声明)
尝试使用tree.findall(".//table")
而不是tree.xpath("//table")
。我不确定它是否会有所作为,但我几小时前在我自己的项目中使用了这种语法而没有问题,作为奖励,它与非LXML ElementTree API兼容。
我建议的另一个主要问题是使用Python的内置函数来构建URL,这样您就可以确保您构建的URL在所有情况下都是有效且正确转义的。
如果LXML找不到表格并且浏览器显示存在的表格,我只能想象它是这三个问题之一:
lxml.etree.HTML
。