【问题标题】:Create aggregate df out of webscraping multiple pages using Rvest and Glue使用 Rvest 和 Glue 从网页抓取多个页面中创建聚合 df
【发布时间】:2020-05-31 08:17:31
【问题描述】:

我正在从以下网站的表格中抓取数据

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 时。这是适用于周和位置的代码,但不适用于额外的嵌套 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]]))

基本上,我需要帮助来制作脚手架并将该脚手架转化为包含所有周、位置和页面的最终总数据集。

【问题讨论】:

  • @akrun 这是我想要描述的。
  • 您似乎很想问有关抓取此网站的问题。如果您尝试使用所需的输出使您的问题尽可能清晰,这将很有帮助,以便可以测试和验证可能的解决方案以工作并解决您的问题。这真的甚至涉及刮削部分吗?你只是想用一些变量组合来构建一个字符串(url)列表吗?尝试一次只关注一个特定问题。删除与问题没有直接关系的任何内容。
  • @MrFlick 好吧,我很抱歉,因为我已尽力澄清。是的,我正在尝试学习用 rvest 和胶水刮擦,我只是想尽可能详细,这样人们就可以知道我想要达到什么目的。在一天结束时,所需的输出是一个 df,其中包含所有 17 周内所有四个位置(qb、rb、wr、te)的前 100 行(网站上一次仅显示 25 行) 2019 年。
  • 到目前为止有两个拼写错误(和一个警告); 'week' != 'weeks' 和 'position' != 'positions' 。似乎脚手架只是这两者中的expand.grid。最后出现一条错误消息,表明该网站需要 {page} 的值

标签: r web-scraping rvest


【解决方案1】:

这是我的尝试。我不确定glue() 是否可行。见下文。

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() 来遍历所有 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

【讨论】:

  • 这非常有用。我需要回去对你所做的进行逆向工程以更好地理解我,但我用你在代码中写的前 4 个 url 运行它,然后用前 40 个再次进行抽查,它看起来非常做得好!由于我是抓取新手并且真的只是想学习,我应该专注于学习这个 httr 包吗?还有其他关于刮的建议吗?非常感谢你!编辑ps。有没有办法在此调用 Sys.sleep 以对主机站点有礼貌?
  • @JeffHenderson 欢迎您。例如,您可以在自定义函数的开头添加Sys.sleep(3)Sys.sleep(3); read_html(x) %&gt;%...我想爬虫是你可以通过任何你想尝试的东西来学习的东西。
  • 我不知道你可以扔一个 ;在作为分隔符的函数中。哇。学习了这么多!非常感谢!
猜你喜欢
  • 2018-03-20
  • 2017-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 2019-02-17
  • 2019-02-16
相关资源
最近更新 更多