Использование BeautifulSoup для поиска h3, когда задана только подстрока его заголовка - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь собрать данные с веб-сайта Jeopardy. В частности, я хочу собрать суммы в долларах из таблицы данных с этого сайта :

enter image description here

Отображается как поэтому в l xml:

enter image description here

Я могу сделать это с помощью следующей строки кода:

scores = [int(score.text.replace('$','').replace(',','')) for score in soupEpisode.find('h3', string='Scores at the first commercial break (after clue 15)').findNext('table').find_all('tr')[1].find_all('td')]

Однако бывают случаи, когда таблица отображается немного иначе (с «16» вместо «15»), например так:

enter image description here

В результате часть моего кода, которая делает

soupEpisode.find('h3', string='Scores at the first commercial break (after clue 15)')

, вернет «Нет». Есть ли способ сделать метод find только с подстрокой имени h3? Если бы я мог написать ту же строку кода, просто нуждаясь в подстроке «Scores at the first рекламный ролик», я думаю, что это сработало бы для всех случаев. Спасибо!

Редактировать:

Чтобы проверить, скачайте html версию этого сайта , и должен работать следующий фрагмент кода:

from bs4 import BeautifulSoup

def main(): 
    #episode_file should be "8062.html"
    episode = open(episode_file, encoding="utf-8")
    soupEpisode = BeautifulSoup(episode, 'lxml')
    episode.close()

    first_commercial_break = [int(score.text.replace('$','').replace(',','')) for score in soupEpisode.find('h3', string=string='Scores at the first commercial break (after clue 15)').findNext('table').find_all('tr')[1].find_all('td')]

    return first_commercial_break

1 Ответ

3 голосов
/ 08 апреля 2020

Попробуйте этот код. Он находит h3, включая «Счета на первый коммерческий перерыв», а затем находит таблицу под h3.

from bs4 import BeautifulSoup
from urllib.request import urlopen
html_content = urlopen('http://www.j-archive.com/showgame.php?game_id=6432')
soup = BeautifulSoup(html_content, "lxml")
for h3 in soup.find_all('h3'):
    if 'Scores at the first commercial break' in h3.text:
        new_html_content = str(soup).split(str(h3))[1]

soup = BeautifulSoup(new_html_content, "lxml")
name_list = [td.text for td in soup.find('table').find('tr').find_all('td')]
dollar_list = [td.text for td in soup.find('table').find_all('tr')[1].find_all('td')]

print(name_list)
print(dollar_list)

Результат печати следующий:

['Kevin', 'Julie', 'Bill']
['$2,800', '$0', '$7,200']
...