Использование XPath для поиска списка текстовых полей - PullRequest
0 голосов
/ 15 сентября 2018

Используя скрап и данный HTML-код

<div class="parts"> 
<b>Part1 :</b> 
<a href='/part1.htm'>name 1</a> 
<br> 
<b> Part2 : </b> 
<a href='/part21.htm'>name 21</a>, 
<a href='/part22.htm'>name 22</a>, 
<a href='/part23.htm'>name 23</a>
<br> 
<b> Part3 : </b> 
<a href='/parts31.htm'>name 31</a>, 
<a href='/part32.htm'>name 32</a> 
<br>
</div>

Я хотел бы извлечь каждую серию имен после каждого <b> раздела.

Для первого (где есть только одно имя) это работает с этим

response.xpath('//div[@class="parts"]/b[contains(text(),"Part1")]/following::a/text()').extract_first()

в результате 'имя 1'

Для второго я ожидал, что следующее даст мне список с «именем 21», «именем 22» и «именем 23», то есть остановкой перед следующим тегом b, но возвращенный список также содержит «имя 31» и 'имя 32'

response.xpath('//div[@class="parts"]/b[contains(text(),"Part2")]/following::a/text()')

Как я могу ограничить список только тем, что находится после тега b 'Part2' и перед тегом b 'Part3'?

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Я рекомендую вам использовать другой подход: просто получите ВСЕ имена и для каждого имени получите соответствующий <b> раздел:

data = {}
for name_node in response.xpath('//div[@class="parts"]/a'):
    name = name_node.xpath('./text()').extract_first()
    section_name = name_node.xpath('./preceding-sibling::b[1]/text()').extract_first()

    if section_name not in data:
        data[section_name] = []
    data[section_name].append(name)

print(data["Part2 :"][1])
0 голосов
/ 16 сентября 2018

Один способ выбрать все text() дочерние элементы <a> между <b>, который содержит Part2, и <b>, который содержит Part3:

/div/b[contains(., 'Part2')]/following-sibling::a[following-sibling::b[contains(.,'Part3')]]/text()

Другойможно было бы выбрать всех text() потомков <a>, которые являются следующими братьями и сестрами <b>, которые содержат Part2, и кто из первых предшествующих братьев и сестер <b> содержит Part2:

/div/b[contains(., 'Part2')]/following-sibling::a[preceding-sibling::b[1][contains(.,'Part2')]]/text()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...