#Much of the scraping code is taken from this repository: https://github.com/chmartin/FBref_EPL
#I've made the the necessary changes for the recently added data and for combining it
#standard(stats)
stats = ["player","nationality","position","squad","age","birth_year","games","games_starts","minutes","goals","assists","pens_made","pens_att","cards_yellow","cards_red","goals_per90","assists_per90","goals_assists_per90","goals_pens_per90","goals_assists_pens_per90","xg","npxg","xa","xg_per90","xa_per90","xg_xa_per90","npxg_per90","npxg_xa_per90"]
stats3 = ["players_used","possession","games","games_starts","minutes","goals","assists","pens_made","pens_att","cards_yellow","cards_red","goals_per90","assists_per90","goals_assists_per90","goals_pens_per90","goals_assists_pens_per90","xg","npxg","xa","xg_per90","xa_per90","xg_xa_per90","npxg_per90","npxg_xa_per90"]
#goalkeeping(keepers)
keepers = ["player","nationality","position","squad","age","birth_year","games_gk","games_starts_gk","minutes_gk","goals_against_gk","goals_against_per90_gk","shots_on_target_against","saves","save_pct","wins_gk","draws_gk","losses_gk","clean_sheets","clean_sheets_pct","pens_att_gk","pens_allowed","pens_saved","pens_missed_gk"]
keepers3 = ["players_used","games_gk","games_starts_gk","minutes_gk","goals_against_gk","goals_against_per90_gk","shots_on_target_against","saves","save_pct","wins_gk","draws_gk","losses_gk","clean_sheets","clean_sheets_pct","pens_att_gk","pens_allowed","pens_saved","pens_missed_gk"]
#advance goalkeeping(keepersadv)
keepersadv = ["player","nationality","position","squad","age","birth_year","minutes_90s_gk","goals_against_gk","pens_allowed","free_kick_goals_against_gk","corner_kick_goals_against_gk","own_goals_against_gk","psxg_gk","psnpxg_per_shot_on_target_against","psxg_net_gk","psxg_net_per90_gk","passes_completed_launched_gk","passes_launched_gk","passes_pct_launched_gk","passes_gk","passes_throws_gk","pct_passes_launched_gk","passes_length_avg_gk","goal_kicks","pct_goal_kicks_launched","goal_kick_length_avg","crosses_gk","crosses_stopped_gk","crosses_stopped_pct_gk","def_actions_outside_pen_area_gk","def_actions_outside_pen_area_per90_gk","avg_distance_def_actions_gk"]
keepersadv2 = ["minutes_90s_gk","goals_against_gk","pens_allowed","free_kick_goals_against_gk","corner_kick_goals_against_gk","own_goals_against_gk","psxg_gk","psnpxg_per_shot_on_target_against","psxg_net_gk","psxg_net_per90_gk","passes_completed_launched_gk","passes_launched_gk","passes_pct_launched_gk","passes_gk","passes_throws_gk","pct_passes_launched_gk","passes_length_avg_gk","goal_kicks","pct_goal_kicks_launched","goal_kick_length_avg","crosses_gk","crosses_stopped_gk","crosses_stopped_pct_gk","def_actions_outside_pen_area_gk","def_actions_outside_pen_area_per90_gk","avg_distance_def_actions_gk"]
#shooting(shooting)
shooting = ["player","nationality","position","squad","age","birth_year","minutes_90s","goals","pens_made","pens_att","shots_total","shots_on_target","shots_free_kicks","shots_on_target_pct","shots_total_per90","shots_on_target_per90","goals_per_shot","goals_per_shot_on_target","xg","npxg","npxg_per_shot","xg_net","npxg_net"]
shooting2 = ["minutes_90s","goals","pens_made","pens_att","shots_total","shots_on_target","shots_free_kicks","shots_on_target_pct","shots_total_per90","shots_on_target_per90","goals_per_shot","goals_per_shot_on_target","xg","npxg","npxg_per_shot","xg_net","npxg_net"]
shooting3 = ["goals","pens_made","pens_att","shots_total","shots_on_target","shots_free_kicks","shots_on_target_pct","shots_total_per90","shots_on_target_per90","goals_per_shot","goals_per_shot_on_target","xg","npxg","npxg_per_shot","xg_net","npxg_net"]
#passing(passing)
passing = ["player","nationality","position","squad","age","birth_year","minutes_90s","passes_completed","passes","passes_pct","passes_total_distance","passes_progressive_distance","passes_completed_short","passes_short","passes_pct_short","passes_completed_medium","passes_medium","passes_pct_medium","passes_completed_long","passes_long","passes_pct_long","assists","xa","xa_net","assisted_shots","passes_into_final_third","passes_into_penalty_area","crosses_into_penalty_area","progressive_passes"]
passing2 = ["passes_completed","passes","passes_pct","passes_total_distance","passes_progressive_distance","passes_completed_short","passes_short","passes_pct_short","passes_completed_medium","passes_medium","passes_pct_medium","passes_completed_long","passes_long","passes_pct_long","assists","xa","xa_net","assisted_shots","passes_into_final_third","passes_into_penalty_area","crosses_into_penalty_area","progressive_passes"]
#passtypes(passing_types)
passing_types = ["player","nationality","position","squad","age","birth_year","minutes_90s","passes","passes_live","passes_dead","passes_free_kicks","through_balls","passes_pressure","passes_switches","crosses","corner_kicks","corner_kicks_in","corner_kicks_out","corner_kicks_straight","passes_ground","passes_low","passes_high","passes_left_foot","passes_right_foot","passes_head","throw_ins","passes_other_body","passes_completed","passes_offsides","passes_oob","passes_intercepted","passes_blocked"]
passing_types2 = ["passes","passes_live","passes_dead","passes_free_kicks","through_balls","passes_pressure","passes_switches","crosses","corner_kicks","corner_kicks_in","corner_kicks_out","corner_kicks_straight","passes_ground","passes_low","passes_high","passes_left_foot","passes_right_foot","passes_head","throw_ins","passes_other_body","passes_completed","passes_offsides","passes_oob","passes_intercepted","passes_blocked"]
#goal and shot creation(gca)
gca = ["player","nationality","position","squad","age","birth_year","minutes_90s","sca","sca_per90","sca_passes_live","sca_passes_dead","sca_dribbles","sca_shots","sca_fouled","gca","gca_per90","gca_passes_live","gca_passes_dead","gca_dribbles","gca_shots","gca_fouled","gca_og_for"]
gca2 = ["sca","sca_per90","sca_passes_live","sca_passes_dead","sca_dribbles","sca_shots","sca_fouled","gca","gca_per90","gca_passes_live","gca_passes_dead","gca_dribbles","gca_shots","gca_fouled","gca_og_for"]
#defensive actions(defense)
defense = ["player","nationality","position","squad","age","birth_year","minutes_90s","tackles","tackles_won","tackles_def_3rd","tackles_mid_3rd","tackles_att_3rd","dribble_tackles","dribbles_vs","dribble_tackles_pct","dribbled_past","pressures","pressure_regains","pressure_regain_pct","pressures_def_3rd","pressures_mid_3rd","pressures_att_3rd","blocks","blocked_shots","blocked_shots_saves","blocked_passes","interceptions","clearances","errors"]
defense2 = ["tackles","tackles_won","tackles_def_3rd","tackles_mid_3rd","tackles_att_3rd","dribble_tackles","dribbles_vs","dribble_tackles_pct","dribbled_past","pressures","pressure_regains","pressure_regain_pct","pressures_def_3rd","pressures_mid_3rd","pressures_att_3rd","blocks","blocked_shots","blocked_shots_saves","blocked_passes","interceptions","clearances","errors"]
#possession(possession)
possession = ["player","nationality","position","squad","age","birth_year","minutes_90s","touches","touches_def_pen_area","touches_def_3rd","touches_mid_3rd","touches_att_3rd","touches_att_pen_area","touches_live_ball","dribbles_completed","dribbles","dribbles_completed_pct","players_dribbled_past","nutmegs","carries","carry_distance","carry_progressive_distance","pass_targets","passes_received","passes_received_pct","miscontrols","dispossessed"]
possession2 = ["touches","touches_def_pen_area","touches_def_3rd","touches_mid_3rd","touches_att_3rd","touches_att_pen_area","touches_live_ball","dribbles_completed","dribbles","dribbles_completed_pct","players_dribbled_past","nutmegs","carries","carry_distance","carry_progressive_distance","pass_targets","passes_received","passes_received_pct","miscontrols","dispossessed"]
#playingtime(playingtime)
playingtime = ["player","nationality","position","squad","age","birth_year","minutes_90s","games","minutes","minutes_per_game","minutes_pct","games_starts","minutes_per_start","games_subs","minutes_per_sub","unused_subs","points_per_match","on_goals_for","on_goals_against","plus_minus","plus_minus_per90","plus_minus_wowy","on_xg_for","on_xg_against","xg_plus_minus","xg_plus_minus_per90","xg_plus_minus_wowy"]
playingtime2 = ["games","minutes","minutes_per_game","minutes_pct","games_starts","minutes_per_start","games_subs","minutes_per_sub","unused_subs","points_per_match","on_goals_for","on_goals_against","plus_minus","plus_minus_per90","plus_minus_wowy","on_xg_for","on_xg_against","xg_plus_minus","xg_plus_minus_per90","xg_plus_minus_wowy"]
#miscallaneous(misc)
misc = ["player","nationality","position","squad","age","birth_year","minutes_90s","cards_yellow","cards_red","cards_yellow_red","fouls","fouled","offsides","crosses","interceptions","tackles_won","pens_won","pens_conceded","own_goals","ball_recoveries","aerials_won","aerials_lost","aerials_won_pct"]
misc2 = ["cards_yellow","cards_red","cards_yellow_red","fouls","fouled","offsides","crosses","interceptions","tackles_won","pens_won","pens_conceded","own_goals","ball_recoveries","aerials_won","aerials_lost","aerials_won_pct"]
import requests
from bs4 import BeautifulSoup
import pandas as pd
import re
import sys, getopt
import csv
#Functions to get the data in a dataframe using BeautifulSoup
def get_tables(url):
res = requests.get(url)
## The next two lines get around the issue with comments breaking the parsing.
comm = re.compile("<!--|-->")
soup = BeautifulSoup(comm.sub("",res.text),'lxml')
all_tables = soup.findAll("tbody")
team_table = all_tables[0]
player_table = all_tables[1]
return player_table, team_table
def get_frame(features, player_table):
pre_df_player = dict()
features_wanted_player = features
rows_player = player_table.find_all('tr')
for row in rows_player:
if(row.find('th',{"scope":"row"}) != None):
for f in features_wanted_player:
cell = row.find("td",{"data-stat": f})
a = cell.text.strip().encode()
text=a.decode("utf-8")
if(text == ''):
text = '0'
if((f!='player')&(f!='nationality')&(f!='position')&(f!='squad')&(f!='age')&(f!='birth_year')):
text = float(text.replace(',',''))
if f in pre_df_player:
pre_df_player[f].append(text)
else:
pre_df_player[f] = [text]
df_player = pd.DataFrame.from_dict(pre_df_player)
return df_player
def get_frame_team(features, team_table):
pre_df_squad = dict()
#Note: features does not contain squad name, it requires special treatment
features_wanted_squad = features
rows_squad = team_table.find_all('tr')
for row in rows_squad:
if(row.find('th',{"scope":"row"}) != None):
name = row.find('th',{"data-stat":"squad"}).text.strip().encode().decode("utf-8")
if 'squad' in pre_df_squad:
pre_df_squad['squad'].append(name)
else:
pre_df_squad['squad'] = [name]
for f in features_wanted_squad:
cell = row.find("td",{"data-stat": f})
a = cell.text.strip().encode()
text=a.decode("utf-8")
if(text == ''):
text = '0'
if((f!='player')&(f!='nationality')&(f!='position')&(f!='squad')&(f!='age')&(f!='birth_year')):
text = float(text.replace(',',''))
if f in pre_df_squad:
pre_df_squad[f].append(text)
else:
pre_df_squad[f] = [text]
df_squad = pd.DataFrame.from_dict(pre_df_squad)
return df_squad
def frame_for_category(category,top,end,features):
url = (top + category + end)
player_table, team_table = get_tables(url)
df_player = get_frame(features, player_table)
return df_player
def frame_for_category_team(category,top,end,features):
url = (top + category + end)
player_table, team_table = get_tables(url)
df_team = get_frame_team(features, team_table)
return df_team
#Function to get the player data for outfield player, includes all categories - standard stats, shooting
#passing, passing types, goal and shot creation, defensive actions, possession, and miscallaneous
def get_outfield_data(top, end):
df1 = frame_for_category('stats',top,end,stats)
df2 = frame_for_category('shooting',top,end,shooting2)
df3 = frame_for_category('passing',top,end,passing2)
df4 = frame_for_category('passing_types',top,end,passing_types2)
df5 = frame_for_category('gca',top,end,gca2)
df6 = frame_for_category('defense',top,end,defense2)
df7 = frame_for_category('possession',top,end,possession2)
df8 = frame_for_category('misc',top,end,misc2)
df = pd.concat([df1, df2, df3, df4, df5, df6, df7, df8], axis=1)
df = df.loc[:,~df.columns.duplicated()]
return df
#Function to get keeping and advance goalkeeping data
def get_keeper_data(top,end):
df1 = frame_for_category('keepers',top,end,keepers)
df2 = frame_for_category('keepersadv',top,end,keepersadv2)
df = pd.concat([df1, df2], axis=1)
df = df.loc[:,~df.columns.duplicated()]
return df
#Function to get team-wise data accross all categories as mentioned above
def get_team_data(top,end):
df1 = frame_for_category_team('stats',top,end,stats3)
df2 = frame_for_category_team('keepers',top,end,keepers3)
df3 = frame_for_category_team('keepersadv',top,end,keepersadv2)
df4 = frame_for_category_team('shooting',top,end,shooting3)
df5 = frame_for_category_team('passing',top,end,passing2)
df6 = frame_for_category_team('passing_types',top,end,passing_types2)
df7 = frame_for_category_team('gca',top,end,gca2)
df8 = frame_for_category_team('defense',top,end,defense2)
df9 = frame_for_category_team('possession',top,end,possession2)
df10 = frame_for_category_team('misc',top,end,misc2)
df = pd.concat([df1, df2, df3, df4, df5, df6, df7, df8, df9, df10], axis=1)
df = df.loc[:,~df.columns.duplicated()]
return df
#Go to the 'Standard stats' page of the league
#For Premier League 2019/20, the link is this: https://fbref.com/en/comps/9/stats/Premier-League-Stats
#Remove the 'stats', and pass the first and third part of the link as parameters like below
df_outfield = get_outfield_data('https://fbref.com/en/comps/9/','/Premier-League-Stats')
df_outfield
player | nationality | position | squad | age | birth_year | games | games_starts | minutes | goals | ... | fouls | fouled | offsides | pens_won | pens_conceded | own_goals | ball_recoveries | aerials_won | aerials_lost | aerials_won_pct | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Patrick van Aanholt | nl NED | DF | Crystal Palace | 28 | 1990 | 25.0 | 25.0 | 2162.0 | 3.0 | ... | 6.0 | 6.0 | 2.0 | 0.0 | 0.0 | 1.0 | 203.0 | 10.0 | 14.0 | 41.7 |
1 | Max Aarons | eng ENG | DF | Norwich City | 19 | 2000 | 30.0 | 30.0 | 2700.0 | 0.0 | ... | 26.0 | 40.0 | 2.0 | 1.0 | 0.0 | 0.0 | 236.0 | 18.0 | 36.0 | 33.3 |
2 | Tammy Abraham | eng ENG | FW | Chelsea | 21 | 1997 | 28.0 | 24.0 | 2034.0 | 13.0 | ... | 16.0 | 21.0 | 23.0 | 1.0 | 0.0 | 1.0 | 86.0 | 58.0 | 97.0 | 37.4 |
3 | Che Adams | eng ENG | FW | Southampton | 23 | 1996 | 24.0 | 8.0 | 756.0 | 0.0 | ... | 14.0 | 8.0 | 7.0 | 1.0 | 0.0 | 0.0 | 54.0 | 18.0 | 58.0 | 23.7 |
4 | Adrián | es ESP | GK | Liverpool | 32 | 1987 | 11.0 | 9.0 | 875.0 | 0.0 | ... | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 47.0 | 0.0 | 0.0 | 0.0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
503 | Wilfried Zaha | ci CIV | MF,FW | Crystal Palace | 26 | 1992 | 32.0 | 31.0 | 2740.0 | 3.0 | ... | 42.0 | 99.0 | 15.0 | 1.0 | 0.0 | 0.0 | 208.0 | 11.0 | 25.0 | 30.6 |
504 | Christoph Zimmermann | de GER | DF | Norwich City | 26 | 1993 | 15.0 | 15.0 | 1295.0 | 0.0 | ... | 8.0 | 8.0 | 0.0 | 0.0 | 2.0 | 0.0 | 139.0 | 36.0 | 10.0 | 78.3 |
505 | Oleksandr Zinchenko | ua UKR | DF | Manchester City | 22 | 1996 | 14.0 | 11.0 | 1028.0 | 0.0 | ... | 11.0 | 2.0 | 0.0 | 0.0 | 0.0 | 0.0 | 119.0 | 23.0 | 19.0 | 54.8 |
506 | Richairo Živković | nl NED | FW | Sheffield Utd | 22 | 1996 | 2.0 | 0.0 | 44.0 | 0.0 | ... | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 4.0 | 20.0 |
507 | Kurt Zouma | fr FRA | DF | Chelsea | 24 | 1994 | 22.0 | 19.0 | 1804.0 | 0.0 | ... | 26.0 | 12.0 | 1.0 | 0.0 | 1.0 | 1.0 | 240.0 | 76.0 | 22.0 | 77.6 |
508 rows × 151 columns
#Go to the 'Standard stats' page of the league
#For Premier League 2019/20, the link is this: https://fbref.com/en/comps/9/stats/Premier-League-Stats
#Remove the 'stats', and pass the first and third part of the link as parameters like below
df_team = get_team_data('https://fbref.com/en/comps/9/','/Premier-League-Stats')
df_team
squad | players_used | possession | games | games_starts | minutes | goals | assists | pens_made | pens_att | ... | fouls | fouled | offsides | pens_won | pens_conceded | own_goals | ball_recoveries | aerials_won | aerials_lost | aerials_won_pct | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Arsenal | 29.0 | 54.8 | 32.0 | 352.0 | 2880.0 | 47.0 | 29.0 | 2.0 | 2.0 | ... | 346.0 | 367.0 | 63.0 | 1.0 | 5.0 | 0.0 | 2593.0 | 403.0 | 471.0 | 46.1 |
1 | Aston Villa | 28.0 | 45.2 | 32.0 | 352.0 | 2880.0 | 35.0 | 28.0 | 1.0 | 3.0 | ... | 376.0 | 425.0 | 51.0 | 2.0 | 5.0 | 1.0 | 2860.0 | 581.0 | 644.0 | 47.4 |
2 | Bournemouth | 27.0 | 45.5 | 32.0 | 352.0 | 2880.0 | 29.0 | 19.0 | 1.0 | 1.0 | ... | 304.0 | 331.0 | 54.0 | 1.0 | 3.0 | 0.0 | 3031.0 | 627.0 | 663.0 | 48.6 |
3 | Brighton | 25.0 | 54.0 | 32.0 | 352.0 | 2880.0 | 30.0 | 20.0 | 1.0 | 2.0 | ... | 324.0 | 269.0 | 55.0 | 2.0 | 2.0 | 2.0 | 3010.0 | 549.0 | 468.0 | 54.0 |
4 | Burnley | 22.0 | 40.3 | 32.0 | 352.0 | 2880.0 | 35.0 | 25.0 | 2.0 | 2.0 | ... | 356.0 | 320.0 | 73.0 | 1.0 | 5.0 | 1.0 | 3022.0 | 786.0 | 746.0 | 51.3 |
5 | Chelsea | 27.0 | 60.0 | 32.0 | 352.0 | 2880.0 | 57.0 | 37.0 | 6.0 | 6.0 | ... | 330.0 | 319.0 | 56.0 | 5.0 | 2.0 | 3.0 | 3129.0 | 552.0 | 539.0 | 50.6 |
6 | Crystal Palace | 24.0 | 44.2 | 32.0 | 352.0 | 2880.0 | 26.0 | 18.0 | 3.0 | 3.0 | ... | 349.0 | 393.0 | 48.0 | 2.0 | 1.0 | 2.0 | 2938.0 | 604.0 | 622.0 | 49.3 |
7 | Everton | 23.0 | 48.9 | 32.0 | 352.0 | 2880.0 | 38.0 | 28.0 | 1.0 | 1.0 | ... | 387.0 | 324.0 | 51.0 | 0.0 | 1.0 | 2.0 | 3067.0 | 708.0 | 720.0 | 49.6 |
8 | Leicester City | 21.0 | 57.7 | 32.0 | 352.0 | 2880.0 | 58.0 | 42.0 | 5.0 | 7.0 | ... | 340.0 | 380.0 | 57.0 | 6.0 | 8.0 | 0.0 | 2942.0 | 565.0 | 496.0 | 53.3 |
9 | Liverpool | 24.0 | 63.1 | 32.0 | 352.0 | 2880.0 | 68.0 | 56.0 | 5.0 | 5.0 | ... | 268.0 | 244.0 | 45.0 | 4.0 | 1.0 | 1.0 | 3309.0 | 539.0 | 473.0 | 53.3 |
10 | Manchester City | 23.0 | 65.6 | 32.0 | 352.0 | 2880.0 | 80.0 | 58.0 | 6.0 | 10.0 | ... | 311.0 | 249.0 | 56.0 | 9.0 | 2.0 | 1.0 | 2874.0 | 423.0 | 390.0 | 52.0 |
11 | Manchester Utd | 28.0 | 55.6 | 32.0 | 352.0 | 2880.0 | 50.0 | 34.0 | 7.0 | 11.0 | ... | 357.0 | 365.0 | 45.0 | 10.0 | 1.0 | 1.0 | 2979.0 | 499.0 | 425.0 | 54.0 |
12 | Newcastle Utd | 27.0 | 37.9 | 32.0 | 352.0 | 2880.0 | 33.0 | 25.0 | 0.0 | 1.0 | ... | 310.0 | 347.0 | 67.0 | 0.0 | 0.0 | 1.0 | 2816.0 | 625.0 | 643.0 | 49.3 |
13 | Norwich City | 28.0 | 50.2 | 32.0 | 352.0 | 2880.0 | 24.0 | 17.0 | 2.0 | 2.0 | ... | 306.0 | 371.0 | 41.0 | 1.0 | 7.0 | 2.0 | 2868.0 | 443.0 | 552.0 | 44.5 |
14 | Sheffield Utd | 25.0 | 43.5 | 32.0 | 352.0 | 2880.0 | 30.0 | 21.0 | 1.0 | 1.0 | ... | 346.0 | 249.0 | 66.0 | 1.0 | 2.0 | 0.0 | 3093.0 | 736.0 | 725.0 | 50.4 |
15 | Southampton | 24.0 | 47.9 | 32.0 | 352.0 | 2880.0 | 41.0 | 24.0 | 1.0 | 2.0 | ... | 389.0 | 319.0 | 49.0 | 2.0 | 4.0 | 1.0 | 3341.0 | 683.0 | 758.0 | 47.4 |
16 | Tottenham | 29.0 | 53.1 | 32.0 | 352.0 | 2880.0 | 48.0 | 33.0 | 3.0 | 4.0 | ... | 338.0 | 359.0 | 57.0 | 4.0 | 7.0 | 2.0 | 3081.0 | 529.0 | 539.0 | 49.5 |
17 | Watford | 26.0 | 42.6 | 32.0 | 352.0 | 2880.0 | 28.0 | 19.0 | 4.0 | 5.0 | ... | 398.0 | 272.0 | 54.0 | 4.0 | 6.0 | 3.0 | 3176.0 | 664.0 | 666.0 | 49.9 |
18 | West Ham | 28.0 | 43.2 | 32.0 | 352.0 | 2880.0 | 38.0 | 29.0 | 3.0 | 3.0 | ... | 324.0 | 289.0 | 63.0 | 3.0 | 6.0 | 3.0 | 2973.0 | 659.0 | 669.0 | 49.6 |
19 | Wolves | 20.0 | 47.7 | 32.0 | 352.0 | 2880.0 | 43.0 | 31.0 | 3.0 | 3.0 | ... | 350.0 | 304.0 | 45.0 | 3.0 | 2.0 | 1.0 | 2992.0 | 617.0 | 583.0 | 51.4 |
20 rows × 188 columns
#Save csv file to Desktop
df_team.to_csv('PL1920_Team.csv')
#Similar for keepers like above
df_keeper = get_keeper_data('https://fbref.com/en/comps/Big5/','/players/Big-5-European-Leagues-Stats')
df_keeper
player | nationality | position | squad | age | birth_year | games_gk | games_starts_gk | minutes_gk | goals_against_gk | ... | passes_length_avg_gk | goal_kicks | pct_goal_kicks_launched | goal_kick_length_avg | crosses_gk | crosses_stopped_gk | crosses_stopped_pct_gk | def_actions_outside_pen_area_gk | def_actions_outside_pen_area_per90_gk | avg_distance_def_actions_gk | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Antonio Adán | es ESP | GK | Atlético Madrid | 32 | 1987 | 1.0 | 0.0 | 25.0 | 0.0 | ... | 44.0 | 1.0 | 100.0 | 67.0 | 2.0 | 0.0 | 0.0 | 1.0 | 3.60 | 14.7 |
1 | Adrián | es ESP | GK | Liverpool | 32 | 1987 | 11.0 | 9.0 | 875.0 | 10.0 | ... | 38.3 | 68.0 | 48.5 | 40.4 | 91.0 | 8.0 | 8.8 | 7.0 | 0.72 | 13.3 |
2 | Rúnar Alex Rúnarsson | is ISL | GK | Dijon | 24 | 1995 | 11.0 | 9.0 | 900.0 | 17.0 | ... | 35.9 | 81.0 | 64.2 | 49.2 | 89.0 | 8.0 | 9.0 | 5.0 | 0.50 | 14.1 |
3 | Enrico Alfonso | it ITA | GK | Brescia | 31 | 1988 | 4.0 | 4.0 | 279.0 | 4.0 | ... | 37.0 | 24.0 | 37.5 | 32.8 | 38.0 | 2.0 | 5.3 | 4.0 | 1.29 | 16.3 |
4 | Alisson | br BRA | GK | Liverpool | 26 | 1992 | 23.0 | 23.0 | 2003.0 | 15.0 | ... | 31.9 | 141.0 | 39.7 | 39.1 | 151.0 | 10.0 | 6.6 | 25.0 | 1.12 | 17.1 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
186 | Mauro Vigorito | it ITA | GK | Lecce | 29 | 1990 | 5.0 | 4.0 | 423.0 | 9.0 | ... | 36.3 | 49.0 | 38.8 | 32.2 | 61.0 | 4.0 | 6.6 | 1.0 | 0.21 | 11.6 |
187 | Felix Wiedwald | de GER | GK | Eint Frankfurt | 29 | 1990 | 3.0 | 3.0 | 270.0 | 8.0 | ... | 38.0 | 24.0 | 54.2 | 41.8 | 28.0 | 2.0 | 7.1 | 3.0 | 1.00 | 16.1 |
188 | Yoel | es ESP | GK | Eibar | 30 | 1988 | 2.0 | 2.0 | 90.0 | 0.0 | ... | 61.2 | 8.0 | 87.5 | 66.5 | 16.0 | 1.0 | 6.3 | 2.0 | 2.00 | 17.0 |
189 | Robin Zentner | de GER | GK | Mainz 05 | 24 | 1994 | 22.0 | 22.0 | 1935.0 | 40.0 | ... | 40.8 | 196.0 | 62.8 | 51.6 | 226.0 | 23.0 | 10.2 | 20.0 | 0.93 | 16.2 |
190 | Leopold Zingerle | de GER | GK | Paderborn 07 | 25 | 1994 | 28.0 | 28.0 | 2520.0 | 57.0 | ... | 32.3 | 235.0 | 31.9 | 32.5 | 260.0 | 10.0 | 3.8 | 17.0 | 0.61 | 14.0 |
191 rows × 47 columns
#Save csv file to Desktop
df_outfield.to_csv('PL1920_Outfield.csv')