2016-08-13 181 views
1

我在此工作了很长时间,并尝试了所有类型的命名空间解决方案。但是,我目前的脚本不是打印所需的字符串,而是整个html转储。有谁知道如何解决这个问题?etree&xpath返回整个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

命名空间被继承。如果文档是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) 
+0

非常感谢您的帮助,而且这里需要更简单的表达方式。但是,使用这段代码,我得到以下错误:'File“test.py”,第11行,在 tree = etree.parse(r.text)'...'IOError:我没有在stackoverflow上找到任何类似的错误。 – fahrradlaus

+0

不知道。对我来说,这个错误在'tree = etree.parse(r.text)',这是我甚至没有触及的一行。我的更改只位于最后两行,因此您应该在自己的代码中看到相同的错误。 – Tomalak

+0

之前,它会倾倒整个html文件,因为我在上面的代码中有以下几行'import sys reload(sys) sys.setdefaultencoding('iso-8859-1')'strange ...可能是错的那条线?我认为有必要将html转换为字符串以解析后...如果我把'tree = etree.parse(r)'我得到'TypeError:无法从'响应'中解析' – fahrradlaus

相关问题