【问题标题】:Rselenium scraping table硒刮台
【发布时间】:2021-02-12 21:23:16
【问题描述】:

我想提取位于“https://www.chess.com/member/magnuscarlsen”的“已完成游戏”表中的数据。

下面的代码给了我一个大小为 0 的列表。Selenium 方面的东西似乎正在工作。 Firefox 浏览器在我的桌面上打开并导航到该页面。任何帮助将不胜感激。我已经束手无策了!

rD <- rsDriver(browser="firefox", port=4442L, verbose=F)
remDr <- rD[["client"]]

remDr$navigate("https://www.chess.com/member/magnuscarlsen")

Sys.sleep(5) # give the page time to fully load
html <- remDr$getPageSource()[[1]]

html <- read_html(html)

signal <- html %>%
  html_nodes("table.table-component table-hover archived-games-table")  

【问题讨论】:

  • 鉴于表格的外观,例如它包含各种传达附加信息的图标,如果您包含所需的输出应该是什么样子,这将很有帮助。即使只有几行输出。

标签: r web-scraping rselenium


【解决方案1】:

1 如果您不介意没有准确度数据(我相信没有公布的计算基础),请查看public APIs from Chess.com。你确实得到了所有的动作信息。

特别是通过BigChess 包的实现。我从下面修改了示例:

所有游戏:

library(rjson)
library(bigchess)

user <- "magnuscarlsen"
json_file <- paste0("https://api.chess.com/pub/player/", user,"/games/archives")
json_data <- fromJSON(paste(readLines(json_file), collapse = ""))
result <- data.frame()
for(i in json_data$archives)
  result <- rbind(result, read.pgn(paste0(i, "/pgn")))

单月:

library(bigchess)

df <- read.pgn("https://api.chess.com/pub/player/magnuscarlsen/games/2020/12/pgn")
print(df[df$Date == '2020.12.11'])

  1. 按要求添加您的准确性。该页面上的大部分信息实际上都可以通过 API 获得:

library(bigchess)
#> Warning: package 'bigchess' was built under R version 4.0.3
library(purrr)
library(jsonlite)
#> Warning: package 'jsonlite' was built under R version 4.0.3
#> 
#> Attaching package: 'jsonlite'
#> The following object is masked from 'package:purrr':
#> 
#>     flatten
library(stringr)

try_again <- function(link) {  #https://blog.r-hub.io/2020/04/07/retry-wheel/
  maxtry <- 5
  try <- 1
  resp <- read_json(link)
  while (try <= maxtry && is.null(resp$data)) {
    resp <- read_json(.)
    try <- try + 1
    Sys.sleep(try * .25)
  }
  return(resp)
}

url <- "https://api.chess.com/pub/player/magnuscarlsen/games/2020/12"
result <- data.frame()
result <- read.pgn(paste0(url, "/pgn"))
#> Warning in readLines(con): incomplete final line found on 'https://
#> api.chess.com/pub/player/magnuscarlsen/games/2020/12/pgn'
#> 2021-02-15 20:29:04, successfully imported 47 games
#> 2021-02-15 20:29:04, N moves computed
#> 2021-02-15 20:29:04, extract moves done
#> 2021-02-15 20:29:04, stat moves computed
result <- filter(result, result$Date == "2020.12.11")

data <- read_json(url)
mask <- map(data$games, ~ !is.na(str_match(.x$pgn, 'UTCDate\\s\\"2020\\.12\\.11')[, 1])) %>% unlist()
games <- data$games[mask]
games <- paste0("https://www.chess.com/callback/analysis/game/live/", map(games, ~ str_match(.x$url, "\\d+")[, 1]), "/all")

df <- map_df(games, ~ {
  json_data <- try_again(.x)
  tryCatch(
    data.frame(
      Url = .x,
      WhiteAccuracy = json_data$data$analysis$CAPS$white$all,
      BlackAccuracy = json_data$data$analysis$CAPS$black$all,
      stringsAsFactors = FALSE
    ),
    error = function(e) {
      data.frame(
        Url = .x,
        WhiteAccuracy = NA_integer_,
        BlackAccuracy = NA_integer_,
        stringsAsFactors = FALSE
      )
    }
  )
})

final <- cbind(result, df)
#> Error in .cbind.ts(list(...), .makeNamesTs(...), dframe = FALSE, union = TRUE): non-time series not of the correct length

reprex package (v0.3.0) 于 2021-02-15 创建

【讨论】:

  • 很高兴我可以为此使用 API。我对你脚本的输出感到困惑。如果你去这里:“chess.com/games/archive/magnuscarlsen”,看起来所有的游戏都已经过分析,应该有准确度数据。例如,您的脚本表明,在 2020 年 12 月 11 日 LyonBeast 和 Magnus 之间的 24 场比赛中,只有 6 场被分析,而我上面链接到的存档页面显示每场比赛都被分析。这是什么原因?您的脚本是否有可能只识别 Magnus 自己分析的游戏?
  • 我无法点击该链接,因为它希望我登录。我会看看这个,因为我可以看到至少一个我需要纠正的错误。对不起!
  • 我已经更新,因为我注意到过滤器不起作用。现在我看到了 24 个结果,其中 nrow(filter(final,is.na(final$WhiteAccuracy))) 给了我 3 个没有准确性的结果。如果我使用filter(final,is.na(final$WhiteAccuracy)) %&gt;% .$Url 检查这些网址并访问它们的等价物,我在详细信息选项卡下看不到准确无花果,例如chess.com/analysis/game/live/5941878007chess.com/analysis/game/live/5941963262(无与精度)
  • 有趣。当我去 chess.com/analysis/game/live/5941878007 (你上面的第一个链接)时,我看到 77.5 和 97.0 的准确度,当我去 chess.com/analysis/game/live/5941963262 (你的第二个链接上面)我看到了 88.0 和 89.3 的准确度。
  • 另外,当你输入“result
【解决方案2】:

这是一种可以轻松解决您的问题的方法,因为页面本身只有一个表格。使用 rvest 轻松将其取出。请注意,我使用管道是因为我更喜欢它们。你当然可以不用它们。

library(RSelenium)
library(rvest)

rD <- rsDriver(browser="firefox", port=4443L, verbose=F)
remDr <- rD[["client"]]

remDr$navigate("https://www.chess.com/member/magnuscarlsen")

Sys.sleep(5) # give the page time to fully load
html <- remDr$getPageSource()[[1]]

html <- read_html(html)

##required table
html %>% html_table() %>% .[[1]]

【讨论】:

  • 非常感谢!选择此答案是因为我需要准确度数字。
猜你喜欢
  • 2020-08-23
  • 2017-06-18
  • 2011-03-24
  • 1970-01-01
  • 2019-08-31
  • 2016-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多