Поиск определенного текста в дереве XML и извлечение текста в следующем узле

#xml #web-scraping #xpath #scrapy #contains

#xml #веб-очистка #xpath #шершавый #содержит #scrapy

Вопрос:

Попытка очистить вес смарт-часов от www.currys.co.uk . Веб-сайт не имеет одинаковой структуры для всех продуктов, поэтому, чтобы получить вес каждого продукта, я пытаюсь использовать поиск по ключевым словам, используя xpath :

 //text()[contains(.,'Weight')]
  

Я могу получить текст «Вес», но я хочу получить следующее node : contains фактическое значение веса:

 <tbody>
 <tr>
   <th scope = "row">Weight</th>
   <td> 26.7 g</td>
 <tr>
<body>
  

То, что я ищу, — это получить текст 26.7 g . Я пытался использовать приведенное ниже, но, похоже, это не работает:

 //text()[contains(.,'Weight')]//td
  

Есть предложения? Заранее спасибо.

Ответ №1:

Вы можете использовать following-sibling::td :

 from lxml import etree


txt = '''<tbody>
 <tr>
   <th scope = "row">Weight</th>
   <td> 26.7 g</td>
 </tr>
</tbody>'''

root = etree.fromstring(txt)

for td in root.xpath('//th[contains(., "Weight")]/following-sibling::td'):
    print(td.text)
  

С принтами:

  26.7 g
  

Комментарии:

1. работает блестяще. Спасибо. И просто для дальнейшего использования, чтобы получить предыдущий родственный код, я просто меняю приведенный выше код на » / previous-sibling:: td «?

2. @sophods К сожалению, XPATH не поддерживает функции для поиска предыдущих элементов. Вот CSS / Xpath cheatsheet: devhints.io/xpath Но там .getparent() есть функция lxml — оттуда вы можете искать всех братьев и сестер.