February 8, 2021

Как скачать результаты спортивного турнира с Python

Хотите  иметь реальные данные для запуска инструментов машинного обучения -  столкнетесь с необходимостью парсинга/скрапинга страниц.

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

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

В  целом отмечу, что по мере усложнения программы и включения в нее все  большего числа параметров и обработчиков исключительных ситуаций,  зачастую становиться сложно адаптировать ее к условиям тестирования или  запуска отдельных функциональных элементов (например, скачивание  отдельного турнира). В итоге кажется, что приходится задавать много  ненужных для конкретной ситуации параметров. Опять же можно постоянно  совершенствовать программу для повышения уровня самостоятельности  отдельных модулей, превращая, например, внутренние методы в методы  класса и т.д. Но не стоит забывать о времени, и остановиться при  достижении удовлетворительного результата (мне нравится интерпретация  закона Парето о том, что 20% усилий дают 80% результата).

Допустим, мне удалось скачать информацию обо всех проведенных UFC  поединках. После этого ближайшей задачей является еженедельное   скачивание результатов очередного турнира. Для этого придется всякий раз  предварительно инициализировать экземпляр класса UFCFightsParser:

cur_url = 'http://www.ufcstats.com/event-details/805ad1801eb26abb?'
events_url = 'http://www.ufcstats.com/statistics/events/completed?page=1'

tag_container_events = 'tbody,,'
tag_event = 'a,class,b-link b-link_style_black'
tag_container_el = 'tbody,class,b-fight-details__table-body'
tag_el = 'a,class,b-flag'
page_param = 'page'
delay = 1
ufc_fights = UFCFightsParser(cur_url,events_url,delay,page_param,tag_container_events, tag_event, tag_container_el,tag_el)

При  этом на практике придется менять только первую строку, отвечающую за  адрес конкретного турнира (обо всех параметрах рассказывалось ранее).  Затем понадобится вызвать метод UFCFightsParser - get_item_hrefs (возвращает ссылки на бои) и get_items_params (скачивает содержимое по ссылкам):

items_hrefs = ufc_fights.get_item_hrefs(ufc_fights.cur_url,\
           ufc_fights.tag_container_el,ufc_fights.tag_el, ufc_fights.delay)

ufc_fights.get_items_params(list(set(items_hrefs)))

Результат  будет содержаться в ufc_fights.items_list в виде списка словарей,  который можно сохранить в csv  файл средствами pandas (подробнее читай здесь):

items_list = ufc_fights.items_list
import pandas as pd
frame = pd.DataFrame(items_list)
frame.to_csv('one_event.csv', index=False)

Затем результаты этого турнира можно склеить с итогами других турниров:

frame_new = pd.read_csv('one_event.csv')

frame_old = pd.read_csv('items.csv')

frame = pd.concat([frame_new,frame_old], ignore_index=True)

frame.to_csv('items.csv', index=False)