【问题标题】:etree & xpath return entire html instead of textetree & xpath 返回整个 html 而不是文本
【发布时间】:2016-08-13 19:21:00
【问题描述】:

我在这方面工作了很长时间,并尝试了各种命名空间解决方案。但是,我当前的脚本不是打印所需的字符串,而是打印整个 html 转储。有谁知道如何解决这个问题?

from lxml.html import parse
from lxml import etree
import requests

r = requests.get('https://berlin.kauperts.de/Strassen/Aachener-Strasse-10713-Berlin.html')
tree = etree.parse(r.text)
NSMAP = {'mw':'http://www.w3.org/1999/xhtml/'}
Name2 = tree.xpath('//{http://www.w3.org/1999/xhtml}html/body/div[7]/div/div/div/table/tbody/tr/td[2]/a')
Name3 = tree.find("//html/body/div[7]/div/div/div/table/tbody/tr/td[2]/a")
print(Name2, Name3)

【问题讨论】:

    标签: python parsing xpath lxml


    【解决方案1】:

    命名空间是继承的。如果一个文档是 XHTML,那么文档中的所有节点默认都在 XHTML 命名空间中。

    这意味着您必须在 XPath 表达式的每个步骤中使用该名称空间。在第一步使用它(html)是不够的。

    nsmap 可以帮助您保持代码的可管理性,但您也必须使用它。

    from lxml.html import parse
    import requests
    from lxml import etree
    
    r = requests.get('https://berlin.kauperts.de/Strassen/Aachener-Strasse-10713-Berlin.html')
    tree = etree.parse(r.text)
    nsmap = {'x':'http://www.w3.org/1999/xhtml/'}
    
    path = '//x:body/x:div[7]/x:div/x:div/x:div/x:table/x:tbody/x:tr/x:td[2]/x:a'
    name = tree.findall(path, nsmap)
    

    以上内容笨重且易碎。尝试创建一个更简单的表达式。

    规则:永远不要使用自动生成的 XPath。手动创建“最不具体”的表达式(即最少依赖于不相关的文档结构,如 div 嵌套级别或 -positions)仍然完全符合您的需要。也许是这样的。

    name = tree.findall('//x:table[@class="foo"]//x:td[2]/x:a', nsmap)
    

    【讨论】:

    • 非常感谢您的帮助,这里确实需要更简单的表达方式。但是,使用此代码时,我收到以下错误:File "test.py", line 11, in <module> tree = etree.parse(r.text)...IOError: <exception str() failed> 我在 stackoverflow 上并没有发现任何类似的错误。
    • 不知道。对我来说,tree = etree.parse(r.text) 的错误是我什至没有触及的一条线。我的更改仅在最后两行,因此您实际上应该在自己的代码中看到相同的错误。
    • 之前它会转储整个html文件,因为我在import sys reload(sys) sys.setdefaultencoding('iso-8859-1')上面的代码中有以下几行@奇怪......那行可能有什么问题?我认为将 html 转换为字符串以便在之后解析它是有意义的......如果我输入tree = etree.parse(r) 我得到TypeError: cannot parse from 'Response'
    • 但是r.text已经是一个字符串,所以不需要任何体操。也许网站的源代码是无效的 XHTML(看起来像),这可能会导致 ETree XML 解析器出错。尝试他们解析(可能)损坏的 HTML 的方法,如此处所述lxml.de/parsing.html#parsing-html
    • 是的,这似乎可行。 HTML 解析器还会为您剥离 XHTML 名称空间,以便您可以编写普通的常规 XPath。
    猜你喜欢
    • 1970-01-01
    • 2014-11-15
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    相关资源
    最近更新 更多