2016-08-13 182 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

相關問題