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

Большое спасибо за вашу помощь и в самом деле более простые выражения. Однако с этим кодом я получаю следующую ошибку: «Файл« 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') 'странно ... что может быть неправильно с этой линией? Я подумал, что имеет смысл преобразовать html в строку, чтобы проанализировать его после ... Если я положу 'tree = etree.parse (r)' I get' TypeError: не могу разобрать «Response» – fahrradlaus