Извлечение с помощью .find () второго из двух идентичных 'div' со страницы HTML с BS4 - PullRequest
1 голос
/ 07 июля 2019

Я пытаюсь извлечь второй из двух идентичных 'div' из элемента супа. При разборе корыта и извлечении с помощью метода .find () он получает только первое сверху. Как я могу сказать сценарию пропустить первый и получить следующий, если выполнены некоторые условия? Ниже приведен HTML-код, из которого я хочу извлечь.

<div class="a-row a-size-base a-color-secondary"><span>MPAA Rating: PG (Parental Guidance Suggested)</span></div>
</div>
</div></div>
<div class="sg-1"><div class="sg-2">
<div class="a-section a-spacing-none a-spacing-top-small">
<div class="a-row a-size-base a-color-base">
</div>
</div>
<div class="a-section a-spacing-none a-spacing-top-mini">
<div class="a-row a-size-base a-color-secondary"><span>$0.00 with a CONtv trial on Prime Video Channels</span></div>
</div>

Вот код, который я пытаюсь:

if '$' not in str(product.find('div', {'class': 'a-row a-size-base a-color-secondary'})):
    print('NOT IN')
    pass
    price = product.find('div', {'class': 'a-row a-size-base a-color-secondary'})
    print(price)
else:
    price = product.find('div', {'class': 'a-row a-size-base a-color-secondary'})
    print(price)

Однако, как результат, он все еще дает мне это:

NOT IN
<div class="a-row a-size-base a-color-secondary"><span>MPAA Rating: PG (Parental Guidance Suggested)</span></div>

Скорее это:

<div class="a-row a-size-base a-color-secondary"><span>$0.00 with a CONtv trial on Prime Video Channels</span></div> 

Есть предложения?

Ответы [ 2 ]

1 голос
/ 07 июля 2019

Предполагая, что div теперь напрямую под <body>, вы можете использовать стандартную индексацию Python. В вашем реальном коде замените body в селекторе на соответствующий элемент:

data = '''<div class="a-row a-size-base a-color-secondary"><span>MPAA Rating: PG (Parental Guidance Suggested)</span></div>
</div>
</div></div>
<div class="sg-1"><div class="sg-2">
<div class="a-section a-spacing-none a-spacing-top-small">
<div class="a-row a-size-base a-color-base">
</div>
</div>
<div class="a-section a-spacing-none a-spacing-top-mini">
<div class="a-row a-size-base a-color-secondary"><span>$0.00 with a CONtv trial on Prime Video Channels</span></div>
</div>'''

from bs4 import BeautifulSoup
import re

soup = BeautifulSoup(data, 'lxml')

print(soup.select('body > div')[1].text.strip())

Печать:

$0.00 with a CONtv trial on Prime Video Channels

Обратите внимание на знак > в select() Это означает, что мы хотим, чтобы все <div> напрямую под <body>.

1 голос
/ 07 июля 2019

Вам нужно find_all, а затем индексировать в возвращаемый список, так как find только когда-либо возвращает первое совпадение.Вы можете сделать то же самое с select.С BS4 4.7.1.вы можете использовать :contains для нацеливания innerText элемента на подстроку (например, CONtv trial), а затем использовать select_one, если требуется первое совпадение, или select, если несколько совпадений.Вы хотите сначала проверить if None, прежде чем пытаться получить доступ к .text

from bs4 import BeautifulSoup as bs
import requests

html = '''
<div class="a-row a-size-base a-color-secondary"><span>MPAA Rating: PG (Parental Guidance Suggested)</span></div>
</div>
</div></div>
<div class="sg-1"><div class="sg-2">
<div class="a-section a-spacing-none a-spacing-top-small">
<div class="a-row a-size-base a-color-base">
</div>
</div>
<div class="a-section a-spacing-none a-spacing-top-mini">
<div class="a-row a-size-base a-color-secondary"><span>$0.00 with a CONtv trial on Prime Video Channels</span></div>
</div>
'''
soup = bs(html, 'lxml')
print(soup.find_all('div', {'class': 'a-row a-size-base a-color-secondary'})[1].text)
print(soup.select('.a-color-secondary')[1].text)
print(soup.select_one('.a-color-secondary:contains("CONtv trial")').text)

Цикл с find_all

matches = soup.find_all('div', {'class': 'a-row a-size-base a-color-secondary'})
for item in matches:
    if '$' in str(item):
        print(item.text)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...