我针对以下问题尝试了许多不同的解决方案,而我无法找到目前正在运行的解决方案。 我需要从几个网页的meta标签中获取一些信息。为此我发现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
在所有这些网站中,访问头对象(这只是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
它有效,所以它意味着metas不会连接到头部,但它们会在树中浮动。无论如何,头并不存在。当然,我可以尝试补丁"这个问题访问头部,如果我得到索引超出范围异常我可以导航metas找到我正在寻找的东西,但我期望lxml修复破坏的html(正如我在文档中读到的那样)。
是否有人有同样的问题并能以更好的方式解决它?
答案 0 :(得分: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默认值,即text/
响应的ISO-8859-1。对于这个不正确的特定响应:
>>> 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解析器可以使用存在的<meta>
标头来告诉它使用哪种编码:
>>> tree.find('.//meta').attrib
{'content': 'text/html; charset=utf-8', 'http-equiv': 'Content-Type'}