Красивая страница разбора супа - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь очистить следующую веб-страницу: https://www.racingpost.com с помощью BS. Например, я хочу извлечь все названия курсов . Имена курсов находятся под этим тегом:

<span class="rh-cardsMatrix__courseName">Wincanton</span>

Мой код здесь:

from bs4 import BeautifulSoup
import requests
import pandas as pd
url = "https://www.racingpost.com"
response = requests.get(url)
data = response.text
soup =  BeautifulSoup(data, "html.parser")
pages = soup.find_all('span',{'class':'rh-cardsMatrix__courseName'})
for page in pages:
    print(page.text)

И я ничего не получаю для вывода. Я думаю, что у него есть некоторые проблемы с разбором, и я перепробовал все доступные парсеры для BS. Может кто-нибудь посоветовать здесь? Можно ли вообще это сделать с БС?

Ответы [ 3 ]

1 голос
/ 05 марта 2020

Кажется, что искомые данные скрыты в блоке сценария в конце необработанного HTML.

Вы можете попробовать что-то вроде этого:

import requests
from bs4 import BeautifulSoup
import json
import pandas as pd
from pandas import json_normalize

url = 'https://www.racingpost.com'
res = requests.get(url).text

raw = res.split('cardsMatrix":{"courses":')[1].split(',"date":"2020-03-06","heading":"Tomorrow\'s races"')[0]
data = json.loads(raw)
df = json_normalize(data)

Вывод:

id  abandoned   allWeather  surfaceType     colour  name    countryCode     meetingUrl  hashName    meetingTypeCode     races
0   1083    False   True    Polytrack   3   Chelmsford  GB  /racecards/1083/chelmsford-aw/2020-03-06    chelmsford-aw   Flat    [{'id': 753047, 'abandoned': False, 'result': ...
1   1212    False   False       4   Ffos Las    GB  /racecards/1212/ffos-las/2020-03-06     ffos-las    Jumps   [{'id': 750498, 'abandoned': False, 'result': ...
2   1138    False   True    Polytrack   11  Dundalk     IRE     /racecards/1138/dundalk-aw/2020-03-06   dundalk-aw  Flat    [{'id': 753023, 'abandoned': False, 'result': ...
3   513     False   True    Tapeta  5   Wolverhampton   GB  /racecards/513/wolverhampton-aw/2020-03-06  wolverhampton-aw    Flat    [{'id': 750658, 'abandoned': False, 'result': ...
4   565     False   False       0   Jebel Ali   UAE     /racecards/565/jebel-ali/2020-03-06     jebel-ali   Flat    [{'id': 753155, 'abandoned': False, 'result': ...
5   206     False   False       0   Deauville   FR  /racecards/206/deauville/2020-03-06     deauville   Flat    [{'id': 753186, 'abandoned': False, 'result': ...
6   54  True    False       1   Sandown     GB  /racecards/54/sandown/2020-03-06    sandown     Jumps   [{'id': 750510, 'abandoned': True, 'result': F...
7   30  True    False       2   Leicester   GB  /racecards/30/leicester/2020-03-06  leicester   Jumps   [{'id': 750501, 'abandoned': True, 'result': F...

Предупреждение: имейте в виду, что вам нужно вручную искать строку для правильного разбиения res в конце.

Редактирование: более надежное решение.

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

url = 'https://www.racingpost.com'
res = requests.get(url).content
soup = BeautifulSoup(res)

# salient data seems to be in 20th script block 
data = soup.find_all("script")[19].text
clean = data.split('window.__PRELOADED_STATE = ')[1].split(";\n")[0]
clean = json.loads(clean)
clean.keys()

Вывод:

['stories', 'bookmakers', 'panelTemplate', 'cardsMatrix', 'advertisement']

Затем получить, например, данные, сохраненные на ключе cardsMatrix:

parsed = json_normalize(clean["cardsMatrix"]).courses.values[0]
pd.DataFrame(parsed)

Вывести снова вышеприведенное (но с более надежным решением):

id  abandoned   allWeather  surfaceType     colour  name    countryCode     meetingUrl  hashName    meetingTypeCode     races
0   1083    False   True    Polytrack   3   Chelmsford  GB  /racecards/1083/chelmsford-aw/2020-03-06    chelmsford-aw   Flat    [{'id': 753047, 'abandoned': False, 'result': ...
1   1212    False   False       4   Ffos Las    GB  /racecards/1212/ffos-las/2020-03-06     ffos-las    Jumps   [{'id': 750498, 'abandoned': False, 'result': ...
0 голосов
/ 06 марта 2020

Спасибо Mattbasta за ваш ответ, он направил меня на этот вопрос, который решил мои проблемы: soup = BeautifulSoup (data, "html .parser") pages = soup.find_all ('span', {'class': ' rh-cardsMatrix__courseName '})

PyQt4 to PyQt5 -> mainFrame () устарел, необходимо исправить загрузку веб-страниц

0 голосов
/ 05 марта 2020

Просмотр исходного кода https://www.racingpost.com, элементы не имеют имя класса rh-cardsMatrix__courseName. Запрос этого на странице показывает, что он существует, когда страница отображается. Это говорит о том, что элементы с этим именем класса генерируются с JavaScript, который BeautifulSoup не поддерживает (он не запускается JavaScript).

Вместо этого вы захотите найти конечные точки на веб-странице которые возвращают данные, которые создают эти элементы (например, ищут XHR для данных) и используют их для получения необходимых данных.

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