Rvest正在抓东西,但不是网站上的东西

时间:2018-08-25 19:54:36

标签: r web-scraping rvest

我正尝试从包含小联盟世界系列赛数据的网页上抓取统计数据。该站点上只有一张表,因此我认为。[[1]]应该可以。它确实抓取了一些数据,但是这些名字都不是该特定团队中运动员的名字,并且变量也都没有。这是我的代码

library(rvest)
West <- read_html("https://gc.com/t/summer-2018/west-5b3ad51e396a0500018e8513/stats")
West %>%
html_nodes("table") %>%
  .[[1]] %>%
  html_table

这就是我得到的:

    Batting AB R H RBI[?]
1 J Stevens  4 2 1      -
2 S Roberts  3 0 1      -
3 C Stevens  1 1 0      -
4   R Meier  4 1 2      -

这些都不是西方球队成员的名字。列乱序或错误。我环顾四周,但找不到从中获取什么。我是网络爬虫的新手,所以将不胜感激。

1 个答案:

答案 0 :(得分:0)

已经过去了很长时间,所以OP可能不需要这个,但是也许足够多的例子最终会引起这样的问题。

该站点确实通过XHR请求使用javascript来异步加载内容,但是我们绝对不需要在图片中引入诸如Selenium之类的重量级依赖项来解决大多数此类问题。

您可以在此处看到XHR异步加载的URL(开始使用浏览器开发人员工具进行练习):

enter image description here

现在,该URL也是动态生成的(是令人费解的,次优的Web应用程序设计)。因此,我们需要变得聪明。我使用curlconverter来查看该URL的格式(如下所示,这很讨厌)。但是,这是令人讨厌的制服。因此,您应该能够发布任何团队统计信息URL(它必须与您显示的一样)作为参数,并返回可爱的javascript。这是简短评论的功能:

get_team_stats <- function(team_stats_url) {

  suppressPackageStartupMessages({
    library(httr, warn.conflicts = FALSE, quietly = TRUE)
    library(jsonlite, warn.conflicts = FALSE, quietly = TRUE)
  })

  res <- httr::GET(team_stats_url) # to prime cookies
  httr::stop_for_status(res) # and also validate the team URL

  # extract the team id
  team_id <- gsub("^[[:alpha:]]+\\-", "", strsplit(team_stats_url, "/")[[1]][6])

  httr::GET(
    url = sprintf("https://gc.com/stats/team/%s/", team_id), # use the team id
    query = list(
      stats_requested = "[{\"category\":\"offense\",\"key\":\"GP\"},{\"category\":\"offense\",\"key\":\"PA\"},{\"category\":\"offense\",\"key\":\"AB\"},{\"category\":\"offense\",\"key\":\"H\"},{\"category\":\"offense\",\"key\":\"1B\"},{\"category\":\"offense\",\"key\":\"2B\"},{\"category\":\"offense\",\"key\":\"3B\"},{\"category\":\"offense\",\"key\":\"HR\"},{\"category\":\"offense\",\"key\":\"RBI\"},{\"category\":\"offense\",\"key\":\"R\"},{\"category\":\"offense\",\"key\":\"HBP\"},{\"category\":\"offense\",\"key\":\"ROE\"},{\"category\":\"offense\",\"key\":\"FC\"},{\"category\":\"offense\",\"key\":\"CI\"},{\"category\":\"offense\",\"key\":\"BB\"},{\"category\":\"offense\",\"key\":\"SO\"},{\"category\":\"offense\",\"key\":\"AVG\"},{\"category\":\"offense\",\"key\":\"OBP\"},{\"category\":\"offense\",\"key\":\"SLG\"},{\"category\":\"offense\",\"key\":\"OPS\"}]",
      qualifying_stat = "{\"key\":\"GP\",\"category\":\"offense\"}",
      game_filter = "All"
    )
  ) -> res

  httr::stop_for_status(res) # warn if anything goes wrong

  jsonlite::fromJSON(
    httr::content(res, as = "text", encoding = "UTF-8")
  )

}

让我们一起去吧

team_stats <- get_team_stats("https://gc.com/t/summer-2018/west-5b3ad51e396a0500018e8513/stats")

str(team_stats, 1)
## List of 3
##  $ glossary:'data.frame': 20 obs. of  5 variables:
##  $ players :'data.frame': 14 obs. of  2 variables:
##  $ totals  :'data.frame': 1 obs. of  1 variable: