CoderCastrov logo
CoderCastrov
Python

Парсинг оценок составов команд Английской Премьер-лиги с transfermarkt

Парсинг оценок составов команд Английской Премьер-лиги с transfermarkt
просмотров
6 мин чтение
#Python

Используя Python для оценки стоимости каждой команды Английской Премьер-лиги.

В этой небольшой статье я буду использовать Python для парсинга целевых данных, организации полученных данных в отдельные списки, а затем объединения отдельных списков в один фрейм данных. Transfermarkt предоставляет подробный отчет о сотнях команд и предоставляет несколько интересных метрик, таких как собственная рыночная оценка игрока. Мы можем использовать эту оценку для оценки положения команды в лиге. Весь код предоставлен в конце.

Fig 1. Обзор Transfermarkt.com

Первое действие - импортировать необходимые модули в скрипт.

Fig 1.2 Модули Python

Модуль requests позволяет нам получить доступ к веб-странице, модуль pandas позволяет нам обрабатывать и очищать наши данные, наконец, модуль BeautifulSoup позволяет нам разбирать HTML-код веб-сайтов для получения нужных нам строк.

Fig 1.3 Инициализация веб-скрейпера

Изучая переменную bs_page, которая представляет собой полноценный веб-скрейпер, мы видим кусок HTML-кода. Без подробностей о том, как создается веб-сайт, мы можем использовать функцию "inspect" на веб-странице, чтобы узнать, какой класс HTML нам нужно искать.

Наведите указатель мыши на игрока, например, и щелкните правой кнопкой мыши, затем выберите "inspect". Я рекомендую загрузить расширение SelectorsHub для инспектирования веб-сайтов.

Inspect

Объект, который мы ищем здесь, - это "className", в котором содержатся имена игроков. Для имен игроков это 'spielprofil_tooltip'.

Class Name

Для того чтобы Python мог хранить полученные данные, необходимо создать пустой список. В Python есть несколько основных структур данных, и список здесь пригодится. Чтобы создать пустой список, просто создайте его, как показано. Для удобочитаемости кода я называю эти списки в соответствии с их назначением. Player_names будет содержать список всех игроков. Если мы посмотрим на Player_names, мы увидим только пустой список, который изменится, когда мы будем использовать функцию BeautifulSoups.Find_all.

Empty List

Перед классом в сыром HTML-коде, к которому можно получить доступ, вводится алфавитный символ, прямо перед ранее определенным именем класса. Мы вводим его в функцию find_all, как показано, чтобы скрейпер знал, что мы хотим получить имена игроков.

Find All

Наконец, мы запускаем цикл for, который проходит через всех игроков на странице и добавляет их в ранее созданный пустой словарь.

For Loop

Теперь, если мы инициализируем ранее пустой список, у нас есть список Python со всеми именами игроков. Обратите внимание: имена игроков, кажется, были получены дважды из HTML-кода, я предоставлю простое решение для этой проблемы.

Player Names

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

P1 Dataframe

Теперь наш фрейм данных P1 выглядит так, но эта информация бесполезна без оценок.

P1 Dataframe

Мы можем повторить процесс для длительности контракта игроков и метрик рыночной оценки с transfermarkt, используя тот же процесс и немного изменяя некоторые параметры.

Нижеприведенный код - это тот же процесс, который мы только что выполнили для имен игроков, за исключением того, что на этот раз мы изменили название переменной housing на Player_price и team_price соответственно. Мы также изменили параметры функции find_all BeautifulSoup для метрики рыночной стоимости. Используя инструмент "inspect", мы можем узнать, что имя класса - "rechts hauptlink", и, изучив bs_page еще раз, мы видим, что td - это первый ввод, который нам нужен. Цикл for запускается снова, и мы заменяем специальные символы валюты на пустые строки.

Player Price

После того, как второй цикл for сохраняет наши значения в пустой список player_price, мы можем создать фрейм данных, который требует небольшой работы.

Player Price Dataframe

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

Предпоследним шагом мы упорядочиваем каждый вновь сформированный фрейм данных в список переменных team, и с помощью функции pd.concat мы можем преобразовать этот список в полноценный фрейм данных для использования. Мы называем его Aston Villa и устанавливаем axis = 1, чтобы каждый фрейм данных был столбцом в новом фрейме данных Aston Villa, и мы закончили. :)

Aston Villa Dataframe

Окончательный результат выглядит так, мы ясно видим полное имя игрока, рыночную стоимость и срок его контракта. Повторяя процесс и просто изменяя URL transfermarkt для каждой команды, мы можем собрать один файл, который содержит всю эту информацию.

Combined Dataframe

Чтобы продемонстрировать, что я имею в виду, я изменил URL в начале кода на страницу команды Арсенал, изменил имя переменной на Arsenal и затем использовал pd.merge, чтобы объединить два фрейма данных. Метод похож на SQL, и он просто добавляет данные из первого списка слева. У нас остается объединенный фрейм данных игроков Арсенала и Астон Виллы.

EPLteams = pd.merge(Arsenal, AstonVilla, how = 'outer')

Надеюсь, вам понравилось следовать за мной и увидеть простую версию возможностей Python.

Полный код ниже.

import requests
import pandas as pd
from bs4 import BeautifulSoup

# чтобы сделать запрос на страницу, мы должны сообщить веб-сайту, что мы - браузер, поэтому мы используем переменную headers

headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'}

# адрес страницы данных

page_address = "https://www.transfermarkt.com/fc-arsenal/kader/verein/11"

# загрузка веб-страницы

object_response = requests.get(page_address, headers = headers)

# теперь мы создадим объект beautifulsoup из нашего объекта ответа.
# параметр html parse представляет собой парсер, который мы будем использовать при создании нашего объекта,
# парсер - это программное обеспечение, отвечающее за преобразование записи в структуру данных.

bs_page = BeautifulSoup(object_response.content, 'html.parser')

player_names = [] # список, который будет содержать все имена игроков
# метод find_all может возвращать все теги, которые соответствуют ограничениям в скобках

team_players = bs_page.find_all("a", {"class": "spielprofil_tooltip"})

# имена игроков

for player in team_players:
    player_names.append(player.text)


# цена игрока

player_price = []

team_price = bs_page.find_all("td", {"class":"rechts hauptlink"})

for price in team_price:
    text_price = price.text
    # удаление специальных символов
    text_price = text_price.replace("£" ,"").replace("€" ,"")

    player_price.append(price.text)


p1 = pd.DataFrame(player_names, columns = ["Players"]).drop_duplicates(keep = "first")
p1 = p1[~p1.Players.str.contains(".",regex = False)].reset_index(drop = True)


p2 = pd.DataFrame(player_price, columns = ["Market Value"])



#---------------------------------------------------------------------------------------------------------



player_contracts = []


team_contracts = bs_page.find_all("td", {"class": "zentriert"})

for date in team_contracts:
    player_contracts.append(date.text)

p3 = pd.DataFrame(player_contracts, columns=["Contract_Length"])
p3 = p3[p3.Contract_Length.str.contains("Jun", regex = False)].reset_index(drop = True)

team = [p1,p2,p3]


Arsenal = pd.concat(team,axis=1)