На самом деле ситуация немного сложнее.Неверный результат поиска по XPath
Я пытаюсь получить данные из этого примера HTML:
<li itemprop="itemListElement">
<h4>
<a href="/one" title="page one">one</a>
</h4>
</li>
<li itemprop="itemListElement">
<h4>
<a href="/two" title="page two">two</a>
</h4>
</li>
<li itemprop="itemListElement">
<h4>
<a href="/three" title="page three">three</a>
</h4>
</li>
<li itemprop="itemListElement">
<h4>
<a href="/four" title="page four">four</a>
</h4>
</li>
На данный момент, я использую Python 3 с urllib
и lxml
. По какой-то причине, следующий код не работает, как ожидалось (Пожалуйста, прочитайте комментарии)
scan = []
example_url = "path/to/html"
page = html.fromstring(urllib.request.urlopen(example_url).read())
# Extracting the li elements from the html
for item in page.xpath("//li[@itemprop='itemListElement']"):
scan.append(item)
# At this point, the list 'scan' length is 4 (Nothing wrong)
for list_item in scan:
# This is supposed to print '1' since there's only one match
# Yet, this actually prints '4' (This is wrong)
print(len(list_item.xpath("//h4/a")))
Так как вы можете видеть, первый шаг, чтобы извлечь 4 li
элементы и добавить их в список, затем сканируйте каждый элемент li
на элемент a
, но проблема в том, что каждый элемент li
в scan
на самом деле является всеми четырьмя элементами.
... Или поэтому я думал.
Делая быструю отладку, я обнаружил, что scan
список содержит четыре li
элементов правильно, поэтому я пришел к одному возможному выводу: Там что-то не так с for
петли вышеупомянутой выше.
for list_item in scan:
# This is supposed to print '1' since there's only one match
# Yet, this actually prints '4' (This is wrong)
print(len(list_item.xpath("//h4/a")))
# Something is wrong here...
Единственная реальная проблема заключается в том, что я не могу точно определить ошибку. Что вызывает это?
PS: Я знаю, что есть более простой способ получить из списка a
элементов, но это всего лишь пример html, настоящий содержит много других ... вещей.
'.//' решена проблема, спасибо за ваш ответ. Но почему это произошло? Сначала мы загружаем страницу и получаем ее html, затем извлекаем теги 'li' и помещаем ** каждый из них ** в список. Почему использование '//' имеет значение? Поскольку во втором цикле 'for' мы перебираем каждый из тегов' li', должен быть один и только 'h4' и, следовательно,' a'. EDIT: Может ли быть, что даже после извлечения тегов 'li' у нас все еще есть html? Это может быть настоящим преступником. – Eekan
@Eekan - Правильно, даже после извлечения тегов 'li' запрос XPath все еще имеет доступ ко всему HTML. В вашем примере 'list_item' является ссылкой на элементы' li'. Я верю, что причина этого в том, что XPath позволяет вам перемещаться по дереву и выбирать родительский элемент. Это означает, что 'li' должен быть ссылкой, так что другие элементы вверх по дереву все еще доступны для более сложных запросов. –
Спасибо, приятель. Наверное, я лучше понял XPath. – Eekan