Создайте статистическую информацию из нескольких страниц, используя Rvest и Glue. - PullRequest
1 голос
/ 16 февраля 2020

Я работаю над очисткой данных из таблицы на следующем веб-сайте.

https://fantasy.nfl.com/research/scoringleaders?position=1&statCategory=stats&statSeason=2019&statType=weekStats&statWeek=1

Я хочу создать очистку, которая займет все 17 недель, все четыре позиции (qb, rb, wr, te) и берет первые 4 страницы, чтобы получить первые 100 строк (только 25 показано на странице за раз).

library(tidyverse) 
library(rvest) 
library(glue) 

scrape_19 <- function(week, position, page) {

    Sys.sleep(3)  

    cat(".")

    url <- glue("https://fantasy.nfl.com/research/scoringleaders?{page}position={position}&sort=pts&statCategory=stats&statSeason=2019&statType=weekStats&statWeek={week}")


read_html(url) %>% 
  html_nodes("table") %>%  
  html_table(header = T) %>%
  simplify() %>% 
  first() %>% 
  setNames(paste0(colnames(.), as.character(.[1,]))) %>%
  slice(-1) %>%
  list()
}

Вот все итерации каждого вызова в связке:

week = 1:17;
position = 1:4;
page = c("", "offset=26&", "offset=51&", "offset=76&")

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

scaffold <- tibble(week = weeks,
                   position = list(positions)) %>% tidyr::unnest()
scaffold

tbl_data <- scaffold %>% 
            mutate(data = purrr::map2(week, position, ~scrape_19(.x, .y)[[1]]))

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

1 Ответ

2 голосов
/ 16 февраля 2020

Вот моя попытка. Я не уверен, является ли glue() путь к go. См. Ниже.

first_name <- c("Fred", "Ana", "Bob")
last_name <- c("JOhnson", "Trump")
glue('My name is {first_name} {last_name}.')

Ошибка: переменные должны иметь длину 1 или 3

Ваш случай аналогичен этому примеру. Поэтому я попытался создать все возможные ссылки, используя циклы с map(). Затем я проверил, все ли URL существуют или нет. Я использовал map_dfr(), чтобы l oop через все URL и связать все фреймы данных. В этом процессе я также добавил информацию о неделе и позиции. Если позиция 1, это QB. При необходимости замените эти цифры самостоятельно. Обратите внимание, что в этой демонстрации я удалил четыре URL-адреса.

library(httr)
library(rvest)
library(tidyverse)

# Create all URLs.

# Create 4 base URLs
paste("https://fantasy.nfl.com/research/scoringleaders?",
      c("", "offset=26&", "offset=51&", "offset=76&"),
      "position={position}&sort=pts&statCategory=stats&statSeason=2019&statType=weekStats&statWeek={week}",
      sep = "") -> mytemp

# For each base URL, create 4 URLs. (4 x 4 = 16 URLs)
map(.x = 1:4,
    .f = function(x){gsub(x = mytemp, pattern = "\\{position\\}", replacement = x)}) %>% 
unlist -> mytemp

# For each of the 16 URLs, create 17 URLs
map(.x = 1:17,
    .f = function(x){gsub(x = mytemp, pattern = "\\{week\\}", replacement = x)}) %>% 
unlist -> myurls


# Check if any URLs are invalid
sapply(myurls, url_success) %>% table

# TRUE 
#  272 

# Scrape the tables
map_dfr(.x = myurls[1:4],
        .f = function(x){read_html(x) %>% 
                         html_nodes("table") %>% 
                         html_table() %>% 
                         simplify() %>% 
                         first() %>% 
                         setNames(paste0(colnames(.), as.character(.[1,]))) %>% 
                         slice(-1) %>% 
                         mutate(position = str_extract(string = x, pattern = "(?<=position=)\\d+(?=&)"),
                                week = str_extract(string = x, pattern = "(?<=statWeek=)\\d+"))},
        .id = "url") -> foo


   url Rank                               Player  Opp PassingYds PassingTD PassingInt RushingYds RushingTD ReceivingRec ReceivingYds
1    1    1               Lamar Jackson QB - BAL @MIA        324         5          -          6         -            -            -
2    1    2                Dak Prescott QB - DAL  NYG        405         4          -         12         -            -            -
3    1    3              Deshaun Watson QB - HOU  @NO        268         3          1         40         1            -            -
4    1    4            Matthew Stafford QB - DET @ARI        385         3          -         22         -            -            -
5    1    5              Patrick Mahomes QB - KC @JAX        378         3          -          2         -            -            -

   ReceivingTD RetTD MiscFumTD Misc2PT FumLost FantasyPoints position week
1            -     -         -       -       -         33.56        1    1
2            -     -         -       -       -         33.40        1    1
3            -     -         -       -       -         30.72        1    1
4            -     -         -       -       1         27.60        1    1
5            -     -         -       -       -         27.32        1    1
...