我正试图从多个页面中抓取表格。编写了一个带有网址列表的函数:
head(url2)
[1] "http://www.fake URL1/WordDocuments.htm"
[2] "http://www.fake URL2/WordDocuments.htm"
[3] "http://www.fake URL3/WordDocuments.htm"
[5] "http://www.fake URL4/WordDocumentS.htm"
[6] "http://www.fake URL5/WordDocuments.htm"
此函数从url2
:
scrapePage <- function(a,i){
p2<-htmlParse(a[i])
tableNodes = getNodeSet(p2, "//table")
raw.tables<-readHTMLTable(p2, which = 6:length(tableNodes))
parsed.tables<-lapply(raw.tables,function(x) as.data.frame(apply(x,2,function(y) gsub("\\s+", " ", y))))
return(parsed.tables)
}
所以,如果我拨打scrapePage(url2,5)
,我会从第5个网址获取所需的表格。
我现在想循环这个。当然我试过了:
parsed.pages<-list()
for (i in 1:length(url2)){
parsed.pages<-scrapePage(url2,i)
}
但是这给了我:
Error in apply(x, 2, function(y) gsub("\\s+", " ", y)) :
dim(X) must have a positive length
有谁看到我在这里做错了什么?
答案 0 :(得分:0)
尝试以下示例,我得到同样的错误:
apply(NULL, 2, function(x) sum)
apply(numeric(0), 2, function(x) sum) #or similar
所以我猜你的一个链接无法正常工作,并且不包含长度大于0的对象(此处为x)。 我会添加一个
print(paste0("Processing: ", i, " of ", length(url2)))
检查它是哪个项目。
您还可以在if条件下检查您期望的data.frame的长度,如果它的长度/ nrow为0则设置一些NA值。编辑:提及输入a
到scrapePage
现在是url2[1]
,url2[2]
,...
scrapePage <- function(a, verbose = 0){
if (verbose > 0) print(a)
p2<-htmlParse(a)
tableNodes = getNodeSet(p2, "//table")
raw.tables<-readHTMLTable(p2, which = 6:length(tableNodes))
parsed.tables<-lapply(raw.tables,function(x){
if (length(x)>0){
as.data.frame(apply(x,2,function(y) gsub("\\s+", " ", y)))
} else {
return(NA)
}
})
return(parsed.tables)
}
我在应用之前向内部函数添加了一个if条件,以检查x的长度。如果长度大于0(正长度)它应该工作,在另一种情况下NA返回(你当然可以切换到任何其他结果,如0,NULL或类似)。 您还可以使用参数verbose打印已处理的文件。 顺便说一句,您可以将for循环缩短为:
parsed.pages <- lapply(url2, scrapePage, verbose = 1)
答案 1 :(得分:0)
考虑在函数内部使用lapply()
循环sapply()
以删除多个空格:
parsed.tables <- data.frame(sapply(raw.tables, function(x) gsub("\\s+", " ", x)))