加载数千个与ML相关的网络抓取的URL-代码非常慢,需要效率提示

时间:2019-02-10 17:40:57

标签: r for-loop web-scraping vectorization processing-efficiency

我正在通过网络收集来自各种网站的数据以建立股票信号预测算法来构建数据集。我的算法的设置方式涉及对for循环进行分层并加载数千个URL,因为每个链接均涉及库存及其各种定量统计信息。需要帮助提高处理速度。有提示吗?

我已经与一些不同的人讨论了如何解决此问题,有些人推荐了矢量化,但这对我来说是新的。我也尝试过切换到数据表,但是没有看到太多变化。评估行是我学会了以自己想要的方式操作数据的一种技巧,但我认为这可能是速度较慢的原因,但我对此表示怀疑。我也想知道远程处理,但这可能超出了R世界。

对于下面的代码,请想象还有另外4个部分,分别用于我要加载的来自不同网站的其他变量,并且所有这些块都位于更大的for循环中,因为我正在生成两个数据集( c(“培训,测试”))。

tryCatch用于防止代码在加载URL时遇到错误而停止。这些网址会加载到一个列表中,每张股票对应一个-因此它们很长。第二个for循环从URLS抓取数据并将其正确格式化后发布到数据框中。

library(quantmod)
library(readr)
library(rvest)
library(data.table)

urlsmacd <-  vector("list", length = 
eval(parse(text=as.name(paste0("nrow(", set[y], ")", sep = "")))))
for(h in 1:eval(parse(text=as.name(paste0("nrow(", set[y], ")", sep = 
""))))){
  urlsmacd[h] <- paste0('http://www.stockta.com/cgi-bin/analysis.pl? 
symb=',eval(parse(text=as.name(paste0(set[y],"[,1][h]", sep = 
"")))),'&mode=table&table=macd&num1=1', sep = '')
}

for(j in 1:eval(parse(text=as.name(paste0("nrow(", set[y], ")", sep = 
""))))){
  tryCatch({
html <- read_html(urlsmacd[[j]])

#get macd html
MACD26 <- html_nodes(html,'.borderTd~ .borderTd+ .borderTd:nth-child(3) 
font')
MACD26 <- toString(MACD26)
MACD26 <-  gsub("<[^>]+>", "", MACD26)
if(!is.na(MACD26)){
  MACD26 <- as.double(MACD26)
}
eval(parse(text=as.name(paste0(set[y],"$","MACD26[j] <- MACD26"))))

MACD12 <- html_nodes(html,'.borderTd+ .borderTd:nth-child(2) font')
MACD12 <- toString(MACD12)
MACD12 <-  gsub("<[^>]+>", "",MACD12)
if(!is.na(MACD12)){
  MACD12 <- as.double(MACD12)
}
eval(parse(text=as.name(paste0(set[y],"$","MACD12[j] <- MACD12"))))

  }, error=function(e){cat("ERROR :",conditionMessage(e), "\n")})
    }

所有这些说完了,这个过程大约需要6个小时。以这种速度,将这个过程缩短几个小时将使我的项目进展变得非常容易。

感谢StackOverflow的支持者。

1 个答案:

答案 0 :(得分:1)

检查doParallel软件包。它具有foreach循环的并行实现。它使您可以使用更多CPU内核(如果有)来为定义的功能执行并行R会话。例如:

library(doParallel)  
no_cores <- detectCores() - 1  
cl <- makeCluster(no_cores, type="FORK")  
registerDoParallel(cl)  
result <- foreach(i=10:10000) %dopar% 
getPrimeNumbers(i)

如果这些网址存储在列表中,那么还会有一个并行的lapply。

示例摘自这篇出色的文章:

https://www.r-bloggers.com/lets-be-faster-and-more-parallel-in-r-with-doparallel-package/amp/

希望有帮助。