|
| 1 | +#' Get each team Transfermarkt player market values |
| 2 | +#' |
| 3 | +#' Returns data frame of player valuations (in Euros) from transfermarkt.com |
| 4 | +#' for an individual team |
| 5 | +#' |
| 6 | +#' @param each_team_url the url of the required team |
| 7 | +#' @param time_pause the wait time (in seconds) between page loads |
| 8 | +#' |
| 9 | +#' @return returns a dataframe of player valuations for a team |
| 10 | +#' |
| 11 | +#' @importFrom magrittr %>% |
| 12 | +#' @importFrom rlang .data |
| 13 | +#' |
| 14 | +#' @export |
| 15 | +#' |
| 16 | + |
| 17 | +tm_each_team_player_market_val <- function(each_team_url, time_pause = 15) { |
| 18 | + |
| 19 | + main_url <- "https://www.transfermarkt.com" |
| 20 | + |
| 21 | + # there now appears to be an errorneous URL so will remove that manually: |
| 22 | + if(any(grepl("com#", each_team_url))) { |
| 23 | + each_team_url <- each_team_url[-grep(".com#", each_team_url)] |
| 24 | + } |
| 25 | + |
| 26 | + each_team_url <- gsub("startseite", "kader", each_team_url) %>% |
| 27 | + paste0(., "/plus/1") |
| 28 | + |
| 29 | + Sys.sleep(time_pause) |
| 30 | + |
| 31 | + team_page <- xml2::read_html(each_team_url) |
| 32 | + |
| 33 | + comp_name <- team_page |> rvest::html_elements(".data-header__club a") |> rvest::html_text() |> trimws() |
| 34 | + country <- team_page |> rvest::html_elements(".data-header__content a img") |> rvest::html_attr("title") |
| 35 | + season_start_year <- gsub(".*saison_id/", "", each_team_url) |> gsub("/plus/1", "", x=_) |> as.numeric() |
| 36 | + |
| 37 | + team_data <- team_page %>% rvest::html_nodes("#yw1") %>% rvest::html_nodes(".items") %>% rvest::html_node("tbody") |
| 38 | + |
| 39 | + tab_head_names <- team_page %>% rvest::html_nodes("#yw1") %>% rvest::html_nodes(".items") %>% rvest::html_nodes("th") %>% rvest::html_text() |
| 40 | + |
| 41 | + # team name |
| 42 | + squad <- team_page %>% rvest::html_node(".data-header__headline-wrapper--oswald") %>% rvest::html_text() %>% stringr::str_squish() |
| 43 | + # numbers |
| 44 | + player_num <- team_data %>% rvest::html_nodes(".rn_nummer") %>% rvest::html_text() |
| 45 | + if(length(player_num) == 0) { |
| 46 | + player_num <- NA_character_ |
| 47 | + } |
| 48 | + # player names |
| 49 | + player_name <- team_data %>% rvest::html_nodes(".inline-table a") %>% rvest::html_text() %>% stringr::str_squish() |
| 50 | + if(length(player_name) == 0) { |
| 51 | + player_name <- NA_character_ |
| 52 | + } |
| 53 | + # player_url |
| 54 | + player_url <- team_data %>% rvest::html_nodes(".inline-table a") %>% rvest::html_attr("href") %>% |
| 55 | + paste0(main_url, .) |
| 56 | + if(length(player_url) == 0) { |
| 57 | + player_url <- NA_character_ |
| 58 | + } |
| 59 | + # player position |
| 60 | + player_position <- team_data %>% rvest::html_nodes(".inline-table tr+ tr td") %>% rvest::html_text() %>% stringr::str_squish() |
| 61 | + if(length(player_position) == 0) { |
| 62 | + player_position <- NA_character_ |
| 63 | + } |
| 64 | + # birthdate |
| 65 | + player_birthday <- team_data %>% rvest::html_nodes("td:nth-child(3)") %>% rvest::html_text() |
| 66 | + if(length(player_birthday) == 0) { |
| 67 | + player_birthday <- NA_character_ |
| 68 | + } |
| 69 | + # player_nationality |
| 70 | + player_nationality <- c() |
| 71 | + player_nat <- team_data %>% rvest::html_nodes(".flaggenrahmen:nth-child(1)") |
| 72 | + if(length(player_nat) == 0) { |
| 73 | + player_nationality <- NA_character_ |
| 74 | + } else { |
| 75 | + for(i in 1:length(player_nat)) { |
| 76 | + player_nationality <- c(player_nationality, xml2::xml_attrs(player_nat[[i]])[["title"]]) |
| 77 | + } |
| 78 | + } |
| 79 | + # current club - only for previous seasons, not current: |
| 80 | + current_club_idx <- grep("Current club", tab_head_names) |
| 81 | + if(length(current_club_idx) == 0) { |
| 82 | + current_club <- NA_character_ |
| 83 | + } else { |
| 84 | + c_club <- team_data %>% rvest::html_nodes(paste0("td:nth-child(", current_club_idx,")")) |
| 85 | + current_club <- c() |
| 86 | + for(cc in c_club) { |
| 87 | + each_current <- cc %>% rvest::html_nodes("a") %>% rvest::html_nodes("img") %>% rvest::html_attr("alt") |
| 88 | + if(length(each_current) == 0) { |
| 89 | + each_current <- NA_character_ |
| 90 | + } |
| 91 | + current_club <- c(current_club, each_current) |
| 92 | + } |
| 93 | + } |
| 94 | + # player height |
| 95 | + height_idx <- grep("Height", tab_head_names) |
| 96 | + if(length(height_idx) == 0) { |
| 97 | + player_height_mtrs <- NA_character_ |
| 98 | + } else { |
| 99 | + suppressWarnings(player_height_mtrs <- team_data %>% rvest::html_nodes(paste0("td:nth-child(", height_idx, ")")) %>% rvest::html_text() %>% |
| 100 | + gsub(",", "\\.", .) %>% gsub("m", "", .) %>% stringr::str_squish() %>% as.numeric()) |
| 101 | + } |
| 102 | + # player_foot |
| 103 | + foot_idx <- grep("Foot", tab_head_names) |
| 104 | + if(length(foot_idx) == 0) { |
| 105 | + player_foot <- NA_character_ |
| 106 | + } else { |
| 107 | + player_foot <- team_data %>% rvest::html_nodes(paste0("td:nth-child(", foot_idx,")")) %>% rvest::html_text() |
| 108 | + } |
| 109 | + # date joined club |
| 110 | + joined_idx <- grep("Joined", tab_head_names) |
| 111 | + if(length(joined_idx) == 0) { |
| 112 | + date_joined <- NA_character_ |
| 113 | + } else { |
| 114 | + date_joined <- team_data %>% rvest::html_nodes(paste0("td:nth-child(", joined_idx, ")")) %>% rvest::html_text() |
| 115 | + } |
| 116 | + # joined from |
| 117 | + from_idx <- grep("Signed from", tab_head_names) |
| 118 | + if(length(from_idx) == 0) { |
| 119 | + joined_from <- NA_character_ |
| 120 | + } else { |
| 121 | + p_club <- tryCatch(team_data %>% rvest::html_nodes(paste0("td:nth-child(", from_idx, ")")), error = function(e) NA) |
| 122 | + joined_from <- c() |
| 123 | + for(pc in p_club) { |
| 124 | + each_past <- pc %>% rvest::html_nodes("a") %>% rvest::html_nodes("img") %>% rvest::html_attr("alt") |
| 125 | + if(length(each_past) == 0) { |
| 126 | + each_past <- NA_character_ |
| 127 | + } |
| 128 | + joined_from <- c(joined_from, each_past) |
| 129 | + } |
| 130 | + } |
| 131 | + # contract expiry |
| 132 | + contract_idx <- grep("Contract", tab_head_names) |
| 133 | + if(length(contract_idx) == 0) { |
| 134 | + contract_expiry <- NA_character_ |
| 135 | + } else { |
| 136 | + contract_expiry <- team_data %>% rvest::html_nodes(paste0("td:nth-child(", contract_idx, ")")) %>% rvest::html_text() |
| 137 | + } |
| 138 | + # value |
| 139 | + player_market_value <- team_data %>% rvest::html_nodes(".rechts.hauptlink") %>% rvest::html_text() |
| 140 | + if(length(player_market_value) == 0) { |
| 141 | + player_market_value <- NA_character_ |
| 142 | + } |
| 143 | + |
| 144 | + suppressWarnings(team_df <- cbind(squad, player_num, player_name, player_url, player_position, player_birthday, player_nationality, current_club, |
| 145 | + player_height_mtrs, player_foot, date_joined, joined_from, contract_expiry, player_market_value) %>% data.frame()) |
| 146 | + |
| 147 | + team_df <- team_df |> |
| 148 | + dplyr::mutate(comp_name = comp_name, |
| 149 | + season_start_year = season_start_year, |
| 150 | + country = country) |> |
| 151 | + dplyr::mutate(player_market_value_euro = mapply(.convert_value_to_numeric, player_market_value)) %>% |
| 152 | + dplyr::mutate(date_joined = .tm_fix_dates(.data[["date_joined"]]), |
| 153 | + contract_expiry = .tm_fix_dates(.data[["contract_expiry"]])) %>% |
| 154 | + tidyr::separate(., player_birthday, into = c("Month", "Day", "Year"), sep = " ", remove = F) %>% suppressWarnings() |> |
| 155 | + dplyr::mutate(player_age = gsub(".*\\(", "", .data[["player_birthday"]]) %>% gsub("\\)", "", .), |
| 156 | + Day = gsub(",", "", .data[["Day"]]) %>% as.numeric(), |
| 157 | + Year = as.numeric(gsub("\\(.*", "", .data[["Year"]])), |
| 158 | + Month = match(.data[["Month"]], month.abb), |
| 159 | + player_dob = suppressWarnings(lubridate::ymd(paste(.data[["Year"]], .data[["Month"]], .data[["Day"]], sep = "-")))) %>% |
| 160 | + dplyr::mutate(player_age = as.numeric(gsub("\\D", "", .data[["player_age"]]))) %>% |
| 161 | + dplyr::select(.data[["comp_name"]], .data[["country"]], .data[["season_start_year"]], .data[["squad"]], .data[["player_num"]], .data[["player_name"]], .data[["player_position"]], .data[["player_dob"]], .data[["player_age"]], .data[["player_nationality"]], .data[["current_club"]], |
| 162 | + .data[["player_height_mtrs"]], .data[["player_foot"]], .data[["date_joined"]], .data[["joined_from"]], .data[["contract_expiry"]], .data[["player_market_value_euro"]], .data[["player_url"]]) |
| 163 | + |
| 164 | + |
| 165 | + return(team_df) |
| 166 | + |
| 167 | +} |
| 168 | + |
| 169 | + |
| 170 | + |
| 171 | + |
1 | 172 | #' Get Transfermarkt player market values |
2 | 173 | #' |
3 | 174 | #' Returns data frame of player valuations (in Euros) from transfermarkt.com |
|
0 commit comments