Как получить текст изнутри или снаружи одновременно с xpath? - PullRequest
0 голосов
/ 03 февраля 2020

У меня проблема с использованием xpath для получения противоречивого прайс-листа

Пример

<td><span="green">$33.99</span></td>
<td>Out of stock</td>
<td><span="green">$27.99</span></td>
<td><span="green">$35.00</span></td>

Как получить цену внутри диапазона и Нет в наличии на в то же время? Потому что я получаю только $ 33,99 или что-нибудь, что имеет span и текст, который не находится внутри span, был пропущен. И это испортило порядок.

Неудачная попытка, которую я использовал с обновлением из решения @ piratefache (Scrapy)

product_prices_tds = response.xpath('//td/')
    product_prices = []

    for td in product_prices_tds:
        if td.xpath('//span'):
            product_prices = td.xpath('//span/text()').extract()
        else:
            product_prices = td.xpath('//text()').extract()

    for n in range(len(product_names)):
        items['price'] = product_prices[n]
        yield items

Не работает, потому что product_prices не получает правильный текст получить со всего места. Не только внутри или снаружи, как я намеревался.

Обновление Для того, кто пришел позже. Я исправил свой код благодаря @ piratefache's. Вот исправленный фрагмент для тех, кто хочет использовать позже.

product_prices_tds = response.xpath('//td')
    product_prices = []

    for td in product_prices_tds:
        if td.xpath('span'):
            product_prices.append(td.xpath('span//text()').extract())
        else:
            product_prices.append(td.xpath('/text()').extract())

    for n in range(len(product_names)):
        items['price'] = product_prices[n]
        yield items

Ответы [ 2 ]

0 голосов
/ 03 февраля 2020

Решение XPath (от 2.0 и выше) (те же логики c, что и @piratefache, опубликованный ранее):

for $td in //td 
return 
if ($td[span]) 
then
$td/span/data() 
else 
$td/data()

Применяется

<root>
    <td>
        <span>$33.99</span>
    </td>
    <td>Out of stock</td>
    <td>
        <span>$27.99</span>
    </td>
    <td>
        <span>$35.00</span>
    </td>
</root>

возвращает

 $33.99
 Out of stock
 $27.99
 $35.00

Кстати: <span="green"> недействительно XML. Возможно, отсутствует атрибут @color или аналогичный (?)

0 голосов
/ 03 февраля 2020

См. Редактирование ниже с Scrapy

На основе вашего кода html, используя библиотеку BeautifulSoup, вы можете получить информацию следующим образом:

from bs4 import BeautifulSoup

page = """<td><span="green">$33.99</span></td>
          <td>Out of stock</td>
            <td><span="green">$27.99</span></td>
            <td><span="green">$35.00</span></td>"""

soup = BeautifulSoup(page, features="lxml")
tds = soup.body.findAll('td') # get all spans

for td in tds:

    # if attribute span exist
    if td.find('span'):
        print(td.find('span').text)
    # if not, just print inner text (here it's out of stock)
    else:
        print(td.text)

output :

$33.99
Out of stock
$27.99
$35.00

С помощью Scrapy:

import scrapy

page = """<td><span="green">$33.99</span></td>
          <td>Out of stock</td>
            <td><span="green">$27.99</span></td>
            <td><span="green">$35.00</span></td>"""

response = scrapy.Selector(text=page, type="html")
tds = response.xpath('//td')

for td in tds:

    # if attribute span exist
    if td.xpath('span'):
        print(td.xpath('span//text()')[0].extract())
    # if not, just print inner text (here it's out of stock)
    else:
        print(td.xpath('text()')[0].extract())

Вывод:

$33.99
Out of stock
$27.99
$35.00
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...