Лучшие практики XPath для извлечения данных из поля, формат которого различается

Я использовал Python 3.8, XPath и Scrapy, где все, казалось, работало. Я принял свои выражения XPath как должное.

Теперь я должен использовать Python 3.8, XPath и lxml.html, и все гораздо менее щадяще. Например, используя этот URL и этот XPath:

//dt[text()='Services/Products']/following-sibling::dd[1]

Я бы вернул абзац или список в зависимости от внутреннего html. Вот как я пытаюсь извлечь текст сейчас:

data = response.text
tree = html.fromstring(data)
Services_Product = tree.xpath("//dt[text()='Services/Products']/following-sibling::dd[1]")

который возвращает это: Services_Product[], который представляет собой список элементов li для его страницы, но в других случаях это поле может быть любым из следующих:

<dd>some text</dd>
or
<dd><p>some text</p></dd>
or
<dd>
  <ul>
    <li>some text</li>
    <li>some text</li>
  </ul>
</dd>
or
<dd>
  <ul>
    <li><p>some text</p></li>
    <li><p>some text</p></li>
  </ul>
</dd>

Каков наилучший способ извлечения текста из подобных ситуаций, когда целевым полем может быть несколько разных вещей?

Я использовал этот тестовый код, чтобы увидеть, какие у меня есть варианты:

file = open('html_01.txt', 'r')
data = file.read()
tree = html.fromstring(data)
Services_Product = tree.xpath("//dt[text()='Services/Products']/following-sibling::dd[1]")
stuff = Services_Product[0].xpath("//li")
for elem in stuff:
    print(elem[0][0].text)

Это вернуло это: Здоровье Врачи здоровья Врачи здоровья

Что не правильно. Вот снимок экрана в Google Chrome: Инструмент Xpath в Google Chrome вместе с рассматриваемым html< /а>

Каков наилучший способ очистить эти данные с помощью Python и Xpath или других вариантов? Спасибо.


person spacedog    schedule 30.04.2021    source источник
comment
Лучшая практика — это то, что дает вам желаемый результат.   -  person zx485    schedule 30.04.2021


Ответы (1)


Потратив часы на гугление, а затем написав этот пост выше, я просто пришел к выводу: старый код:

Services_Product = tree.xpath("//dt[text()='Services/Products']/following-sibling::dd[1]")
stuff = Services_Product[0].xpath("//li")

и новый код, который возвращает хороший список текста:

Services_Product = tree.xpath("//dt[text()='Services/Products']/following-sibling::dd[1]")
stuff = Services_Product[0].xpath("//li/text()")

добавьте /text() в конце, исправив это.

person spacedog    schedule 30.04.2021