R中的readHTMLTable - 跳过NULL值

时间:2017-02-16 09:32:17

标签: html r web-scraping null

我正在尝试使用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值时停止。非常感谢任何帮助 - 非常感谢。

2 个答案:

答案 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)

最后一行丢弃所有“失败”的尝试。如果你想保留它们只是放弃最后一行