etree& xpath返回整个html而不是文本

时间:2016-08-13 19:21:00

标签: python parsing xpath lxml

我已经解决了很长一段时间,并尝试了所有类型的命名空间解决方案。但是,我当前的脚本不打印所需的字符串,而是整个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)

1 个答案:

答案 0 :(得分: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嵌套级别或位置),它们仍然与您需要的完全匹配。也许就是这样。

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