【问题标题】:Use readHTMLTable over a List of Dates and Create New Date Column with Data在日期列表上使用 readHTMLTable 并使用数据创建新的日期列
【发布时间】:2016-01-25 22:25:09
【问题描述】:

我正在尝试编写一个循环来对我通过公式提供的连续日期列表执行readHTMLTable()。我已成功导入日期之间的所有数据。但是,该数据没有日期列,因此使用我提供循环的日期序列,我希望循环读取 HTMLTable,然后添加一个带有用于该迭代的日期的新列。

这是我目前所拥有的:

library(XML)
library(RCurl)
library(plyr)

# create the days
x <- seq(as.Date("2015-04-10"), as.Date("2015-04-15"), by = "day")

# create a url template for sprintf()
utmp <- "http://www.basketball-reference.com/friv/dailyleaders.cgi?month=%d&day=%d&year=%d"

# convert to numeric matrix after splitting for year, month, day
m <- do.call(rbind, lapply(strsplit(as.character(x), "-"), type.convert))

# create the list to hold the results
tables <- vector("list", length(m))

# get the tables
for(i in seq_len(nrow(m))) {
  # create the url for the day and if it exists, read it - if not, NULL
  tables[[i]] <- if(url.exists(u <- sprintf(utmp, m[i, 2], m[i, 3], m[i, 1]))) 
    readHTMLTable(u, stringsAsFactors = FALSE)
  else NULL
}

data <- ldply(tables,data.frame)

因此,基本上,我希望我的最终数据框以 m 为新列,名为 data$Date

感谢您的帮助,如果您需要任何说明,请告诉我!

【问题讨论】:

标签: xml r web-scraping rcurl


【解决方案1】:

考虑使用mapply()(apply 系列的多元函数),您可以在其中传递日期列表、url 和表迭代器以下载 html 表。您可以避免矩阵处理,因为format() 可以提取部分日期类型。此外,请考虑不要将 NULL 用于不存在的 url,因为它可能不会在之后绑定。只需过滤掉空元素。

# LIST OF DATES
x <- lapply(0:5, function(i) as.Date("2015-04-10")+i)     

# LIST OF URLS
utmp <- "http://www.basketball-reference.com/friv/dailyleaders.cgi?month=%d&day=%d&year=%d"
urlist <- c(lapply(x, function(i) sprintf(utmp, as.numeric(format(i, '%m')), 
                                                as.numeric(format(i, '%d')), 
                                                as.numeric(format(i, '%y')))))

# USER DEFINED FUNCTION
tables <- vector("list", length(x))
tabledwnld <- function(dt, url, i) {                      
                   if (url.exists(url)) {
                      tableNodes <- readHTMLTable(url)                       
                      tables[[i]] <- tableNodes[[1]]
                      tables[[i]]['Date'] <- dt
                      return(tables)
                   } 
              }
# APPLY ABOVE FUNCTION (RETURNS LARGE MATRIX OF TABLES)
data <- mapply(tabledwnld, x, urlist, 1:6)

# BIND TO DATA FRAME
finaldata <- do.call(rbind, data)

另外,请注意@hrbrmstr 在 cmets 中的警告,如下所示。您可能需要在表格下载中留出空间:

除本段特别规定外,您同意不 使用或启动任何自动化系统,包括但不限于, 访问 站点以向站点服务器发送更多请求消息的方式 在任何给定的时间段内,比一个典型的人通常会 使用传统的在线网络浏览器在同一时期生产 阅读、查看和提交材料。

【讨论】:

  • 您好,感谢您愿意提供帮助。不幸的是,在我看来,您的代码不可重现。我收到一个关于 tabledwnld 函数中的意外符号的错误,另一个关于无法找到 readHTMLTable 的继承方法的错误,关于无效类型/长度的循环的 dt 部分的错误(闭包/ 0) 在向量分配中,最后是一些关于意外“}”的错误。知道为什么我会看到这些吗?
  • 查看更新。 if 语句未正确包裹在括号中。此外,XML 库的 readHTMLTable 不直接创建数据框,而是检索 URL 的解析 &lt;table&gt; 节点集。
  • 谢谢!代码现在全部运行。但是,我仍然遇到tables 命令返回 0 列表的问题,这使data 命令返回 0 obs。 0 个变量。
  • 我很抱歉。我想我们都在学习!因为害怕网站的政策,我实际上并没有跑。我应该在mapply() 上添加一个返回并将函数结果传递给数据。查看经过测试的更新,finaldata 应该产生 1,222 obs 和 27 vars。 Date 作为最后一列。
  • 完美!这正是我一直在寻找的。非常感谢您的帮助。我知道不想违反 ToS,并且我试图不通过我的抓取使网站超载,所以我会考虑按照@hrbrmstr 的建议添加一个 Sys.sleep 命令。
猜你喜欢
  • 1970-01-01
  • 2019-04-27
  • 2018-12-04
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
相关资源
最近更新 更多