Scrapy / XPATH: как извлечь ТОЛЬКО текст из потомков и себя - PullRequest
0 голосов
/ 25 февраля 2019

У меня есть следующая простая, вложенная структура:

<main>
    <em>bla-bla</em>

    <div class="1">1.1</div>

    <div class="2">2.1</div>

    <div class="2">2.2</div>

    <div class="1">1.2</div>

    <div class="2">
        <span>
            <em>2.3</em>
        </span>
    </div>

    <div class="2">2.4</div>

</main>

Я хотел бы теперь извлечь весь текст из всех узлов, но бороться с вложенным узлом (и т. Д.).

Ожидаемый результат должен быть:

2.1
2.2
2.3
2.4

Попытка что-то вроде:

//div[contains(@class,"2")]/text()

дает

2.1
2.2
<div class="2"><span><em>2.3</em></span></div>
<div class="2"><span><em>2.3</em></span></div>
2.4

Вместо использования прямой XPATH, я также попытался использовать несколько шаговв Scrapy, например:

divs = response.xpath("//div[contains(@class,"2")]")

for div in divs:
   # now check somehow that the div contains an "em" node

Использование

div.xpath("//em")

не работает, поскольку дает все узлы.Используя здесь div.extract () и просматривая возвращаемую строку, я, конечно, мог бы найти поиск по строкам, но это скорее хак и не похоже на правильное решение Scrapy.

Любые предложения, как решитьэто либо напрямую с Xpath, либо с Scrapy в целом было бы очень полезно.

1 Ответ

0 голосов
/ 25 февраля 2019

Что вы думаете о [i.strip() for i in response.xpath('//div[contains(@class, "2")]//text()').extract() if i.strip()]?

Без вскрытия это также дает некоторые пустые случаи:

>>> response.xpath('//div[contains(@class, "2")]//text()').extract()
[u'2.1', u'2.2', u'\n        ', u'\n            ', u'2.3', u'\n        ', u'\n    ', u'2.4']

Поэтому я фильтрую их с помощью strip:

>>> [i.strip() for i in response.xpath('//div[contains(@class, "2")]//text()').extract() if i.strip()]
[u'2.1', u'2.2', u'2.3', u'2.4']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...