Парсинг табличных данных с использованием Python
Table Of Content
- Как спарсить данные об игроках NBA с использованием BeautifulSoup, Selenium и Pandas в Python.
- Подготовка инструментов
- add chromedriverexport PATH="/Users/yourdirectorytoCHROMEDIRVER:$PATH"
- Инспектирование веб-страницы
- Скрапинг таблиц
- Проблема с парсингом нескольких таблиц
- Функция парсинга статистики игроков NBA с basketball-reference
- Кто является MVP НБА в этом сезоне?
- Исследование для определения самого ценного игрока НБА в этом сезоне с использованием машинного обучения.
- Представление важности признаков в классификаторе "Случайный лес"
- Как построить классификатор "Случайный лес", извлечь важность признаков и красиво их представить.
- Проект прогнозирования игр на основе статистики Леброна с использованием трех моделей машинного обучения
- Подробное руководство по решению задачи бинарной классификации с использованием трех различных классификаторов, включая логистическую...
- Руководство по визуализации данных в R-пакете "ggplot2" для статистики игроков НБА
- 6-минутный обзор инструмента визуализации данных R, "ggplot2", примененного к данным НБА.
- Ссылки:
Как спарсить данные об игроках NBA с использованием BeautifulSoup, Selenium и Pandas в Python.
Одна из проблем при выполнении проекта машинного обучения - это сборка набора данных.
Способы сборки данных сильно различаются в зависимости от типа данных, из которых парсинг табличных наборов данных из веб-страниц является одним из наиболее типичных источников. Я долгое время использовал его, чтобы эффективно получить столько данных, сколько мне нужно.
Я уже долгое время пишу о техниках машинного обучения, используя статистику игроков NBA в качестве исходных данных. Одним из самых часто задаваемых мне вопросов является то, могу ли я поделиться данными, потому что люди хотели бы поиграть с ними.
В Азии есть старая поговорка:
Дай человеку рыбу, и ты накормишь его на день; научи человека ловить рыбу, и ты накормишь его на всю жизнь.
Итак, в этой статье я хотел бы поделиться с вами, как спарсить табличные данные с веб-страниц с помощью Python.
Помимо стандартных шагов, я также расскажу о практических проблемах, с которыми я столкнулся, и решениях, чтобы их решить.
Подготовка инструментов
pip install beautifulsoup4
pip install selenium
pip install requests
pip install pandas
Выше приведены коды для установки четырех необходимых пакетов Python, которые в большинстве случаев достаточны.
После успешной установки этих пакетов просто импортируйте их в среду Python.
import requests
from bs4 import BeautifulSoup
from selenium import webdriver
import pandas as pd
Если вы используете Google Chrome в качестве браузера по умолчанию, убедитесь, что chromedriver является исполняемым файлом в вашем PATH. В противном случае вы можете столкнуться с такой же проблемой, как и я, с сообщением об ошибке ниже.
Сообщение: 'chromedriver' исполняемый файл должен находиться в PATH
Чтобы решить эту проблему, просто загрузите chromedriver с https://sites.google.com/a/chromium.org/chromedriver/home и поместите его в исполняемый путь или добавьте его текущее расположение в переменную PATH системы.
Чтобы добавить его расположение в PATH, откройте файл ~/.bash_profile, набрав
vi ~/.bash_profile
Затем добавьте следующую строку в конец файла,
# add chromedriverexport PATH="/Users/yourdirectorytoCHROMEDIRVER:$PATH"
Чтобы проверить, является ли chromedriver исполняемым, просто введите chromedriver в терминале, и вы увидите сообщение от пакета,
На данный момент у нас есть все необходимые инструменты.
Инспектирование веб-страницы
Сначала нам нужно найти целевую страницу. В качестве примера этого руководства я буду использовать страницу статистики игрока НБА на сайте basketball-reference. Вот URL моей целевой страницы:
URL = [https://www.basketball-reference.com/players/i/irvinky01.html](https://www.basketball-reference.com/players/i/irvinky01.html)
Чтобы собрать данные с определенной веб-страницы, нам нужно знать ее структуру через вид разработчика. Щелкните правой кнопкой мыши на странице и щелкните левой кнопкой мыши кнопку «Инспектировать», как показано ниже.
Затем вы увидите скрипт веб-страницы справа, как показано ниже.
Показанная выше информация едва читаема для человека, но после тщательной проверки вы можете обнаружить некоторые шаблоны.
Например, таблицы на странице всегда начинаются с <table …>
и заканчиваются </table>
(выделено синим на графике выше). И эти таблицы именно то, что я хочу получить со страницы.
Скрапинг таблиц
Теперь мы собираемся скрэпить эти таблицы со страницы, используя Beautifulsoup. Стандартный способ получить все таблицы со страницы выглядит так:
page = requests.get(URL)
soup = BeautifulSoup(page.content, 'html.parser')
tables = soup.find_all("table")
где requests.get(URL) получает информацию со страницы, а BeautifulSoup(page.content, 'html.parser') парсит эту информацию.
Затем мы можем применить функцию find_all к распарсенной информации в soup. soup.find_all("table") собирает все блоки информации, которые начинаются с <table>
и заканчиваются </table>
.
Для каждой таблицы в переменной tables, обычно заголовки таблицы начинаются с <th>
, а все ячейки таблицы строк начинаются с <td>
. Таким образом, таблицу можно извлечь и преобразовать в pandas data frame в следующем коде.
table = tables[0]
tab_data = [[cell.text for cell in row.find_all(["th","td"])]
for row in table.find_all("tr")]
df = pd.DataFrame(tab_data)
Сгенерированный data frame выглядит следующим образом:
Чтобы переместить первую строку в заголовки, просто введите
df.columns = df.iloc[0,:]
df.drop(index=0,inplace=True)
Чтобы получить все таблицы со страницы таким же образом, как первую таблицу (tables[0]), я создал словарь и использовал атрибут 'id' каждой таблицы внутри цикла for.
tabs_dic = {}
for table in tables:
tab_name = table['id']
tab_data = [[cell.text for cell in row.find_all(["th","td"])]
for row in table.find_all("tr")]
df = pd.DataFrame(tab_data)
df.columns = df.iloc[0,:]
df.drop(index=0,inplace=True)
#df = df.loc[df.Season != ""]
tabs_dic[tab_name] = df
Я смог извлечь идентификатор таблицы с помощью table['id'], потому что 'id' является атрибутом таблицы, который является 'per_game', как показано ниже:
Таким образом, у меня должны быть все таблицы в формате pandas data frame, размещенные в большом словаре tabs_dic.
Однако у меня возникла проблема...
Проблема с парсингом нескольких таблиц
Когда я впервые попытался изучить номера таблиц на странице игрока, я столкнулся с проблемой, что я парсил только ОДНУ таблицу!
Я использовал find_all("table") как показано в предыдущем коде, как я мог пропустить все остальные таблицы, кроме первой?!
Я проверил типы таблиц на странице и обнаружил, что таблицы, которые ускользнули от моего парсинга, находятся внутри JavaScript.
Затем я использовал Selenium, чтобы решить эту проблему.
driver = webdriver.Chrome()
driver.get(URL)
soup = BeautifulSoup(driver.page_source,'html')
driver.quit()
tables = soup.find_all('table')
Вышеуказанный код решил проблему и успешно получил 75 таблиц.
Я снова был сбит с толку, потому что 75 казалось мне слишком много. Я проверял веб-страницу снова и снова и обнаружил, что хотя некоторые блоки начинаются с <table>
, они содержат только одно или два значения и не являются нужными мне таблицами.
Поэтому я дополнительно изменил код, чтобы выбрать несколько классов таблиц на странице на основе атрибута class таблиц.
tables = soup.find_all('table',{"class":["row_summable sortable stats_table now_sortable","suppress_all sortable stats_table now_sortable","sortable stats_table now_sortable","suppress_glossary sortable stats_table now_sortable"]})
где информация о class передавалась в функцию в формате словаря.
В итоге я получил всего 22 таблицы.
Функция парсинга статистики игроков NBA с basketball-reference
Получение статистики игроков - одна из моих самых частых операций, поэтому я написал большую функцию для будущего использования.
def получить_все_вкладки_страницы_игрока(URL = '[https://www.basketball-reference.com/players/i/irvinky01.html'](https://www.basketball-reference.com/players/i/irvinky01.html')):
driver = webdriver.Chrome()
driver.get(URL)
soup = BeautifulSoup(driver.page_source,'html')
driver.quit()
tables = soup.find_all('table',{"class":["row_summable sortable stats_table now_sortable","suppress_all sortable stats_table now_sortable","sortable stats_table now_sortable","suppress_glossary sortable stats_table now_sortable"]})
tabs_dic = {}
for table in tables:
tab_name = table['id']
tab_data = [[cell.text for cell in row.find_all(["th","td"])] for row in table.find_all("tr")]
df = pd.DataFrame(tab_data)
df.columns = df.iloc[0,:]
df.drop(index=0,inplace=True)
tabs_dic[tab_name] = df
return tabs_dic
Парсинг веб-страницы - это мощный навык, особенно для тех, кто интересуется применением методов машинного обучения в некоторых интересных областях.
Например, навык парсинга является основой для всех следующих постов, которые я написал о машинном обучении и баскетболе.
Кто является MVP НБА в этом сезоне?
Исследование для определения самого ценного игрока НБА в этом сезоне с использованием машинного обучения.
towardsdatascience.com
Представление важности признаков в классификаторе "Случайный лес"
Как построить классификатор "Случайный лес", извлечь важность признаков и красиво их представить.
towardsdatascience.com
Проект прогнозирования игр на основе статистики Леброна с использованием трех моделей машинного обучения
Подробное руководство по решению задачи бинарной классификации с использованием трех различных классификаторов, включая логистическую...
towardsdatascience.com
Обычно, после получения данных в нужном формате, следующим шагом является визуализация данных перед моделированием. Однако, визуализация данных выходит за рамки данной публикации. Те, кто заинтересованы, могут обратиться к одной из моих публикаций по этой теме.
Руководство по визуализации данных в R-пакете "ggplot2" для статистики игроков НБА
6-минутный обзор инструмента визуализации данных R, "ggplot2", примененного к данным НБА.
towardsdatascience.com
Вот и все! Ура! Теперь вы должны знать, как парсить табличные данные с помощью Python.