我正在尝试使用R函数readHTMLTable从www.racingpost.com上的在线数据库中收集数据。我有一个包含30,000个唯一ID的CSV文件,可用于识别单个马匹。不幸的是,少数这些ID导致readHTMLTable返回错误:
(function (classes, fdef, mtable)
中的错误:
无法找到函数'readHTMLTable'的签名'" NULL"'
我的问题是 - 是否可以设置一个包装器函数,它将跳过返回NULL值的ID,然后继续读取剩余的HTML表格?读数在每个NULL值处停止。
到目前为止我所尝试的是:
ids = c(896119, 766254, 790946, 556341, 62736, 660506, 486791, 580134, 0011, 580134)
这些都是有效的马ID,它会返回一个NULL值。然后:
scrapescrape <- function(x) {
link <- paste0("http://www.racingpost.com/horses/horse_home.sd?horse_id=",x)
if (!is.null(readHTMLTable(link, which=2))) {
Frame1 <- readHTMLTable(link, which=2)
}
}
total_data = c(0)
for (id in ids) {
total_data = rbind(total_data, scrapescrape(id))
}
但是,我认为在if语句中返回错误,这意味着函数在达到第一个NULL值时停止。非常感谢任何帮助 - 非常感谢。
答案 0 :(得分:2)
在阅读HTML表格之前,您可以首先分析HTML(检查您获得的页面,并找到识别错误结果的方法)。
但是你也可以确保函数在抛出错误时不返回任何内容(NA),如下所示:
library(XML)
scrapescrape <- function(x) {
link <- paste0("http://www.racingpost.com/horses/horse_home.sd?horse_id=",x)
tryCatch(readHTMLTable(link, which=2), error=function(e){NA})
}
}
ids <- c(896119, 766254, 790946, 556341, 62736, 660506, 486791, 580134, 0011, 580134)
lst <- lapply(ids, scrapescrape)
str(lst)
答案 1 :(得分:2)
使用rvest
即可:
require(rvest)
require(purrr)
paste0("http://www.racingpost.com/horses/horse_home.sd?horse_id=", ids) %>%
map(possibly(~html_session(.) %>%
read_html %>%
html_table(fill = TRUE) %>%
.[[2]],
NULL)) %>%
discard(is.null)
最后一行丢弃所有“失败”的尝试。如果你想保留它们只是放弃最后一行