【问题标题】:parallel computing using foreach for web scraping使用 foreach 进行 Web 抓取的并行计算
【发布时间】:2014-02-28 05:32:57
【问题描述】:

我想使用 foreach 而不是 for 循环进行并行计算,但我真的不知道怎么做。

所以,我想做的是从一堆网页中获取纯文本,并且我有超过 3000 个链接要处理。我需要将所有文本放入一个大文件中。

我知道 for 循环会起作用,但我什至懒得尝试它需要很长时间。

那么我的问题是,如何将for 循环转换为foreach?

这是我的 for 循环:

library(RCurl)  
library(XML)  
urls <- scan("file", what = "char", quote = "", sep = "\n")  #a vector that contains 3000+ urls  
corpus=character()                              
for (i in 1:length(urls)) {      #a loop that the following function will operate on each link 
  html=getURL(urls[i],followlocation=T)  
  doc=htmlParse(html,asText=T)
  text=xpathSApply(doc,"//p",xmlValue)      
  corpus=append(corpus,text)       #append all the individual text  
}

【问题讨论】:

  • 如果你没有在循环中增加corpus,你可以大大加快你的循环。使用lapply/sapply 或预分配corpus。如果您使用lapply 编写此代码并且不使用Windows,则将其并行化就像putting mc in from of it 一样简单。我也不确定 URL 访问是否可以并行化。您可能必须串行使用getURL。如果你想使用foreach,你应该阅读包小插曲。它们非常易读且易于理解。
  • 您使用的是哪个操作系统?
  • @PaulStaab 我正在使用 MacOX
  • @Roland lapply 会从 url 输出文本列表吗?实际上我不确定我是否知道如何使用 lapply,但我会尝试。谢谢!

标签: r foreach parallel-processing


【解决方案1】:

这是一个使用 mclapply 的版本:

library(RCurl)  
library(XML)  
library(parallel)
urls <- c('http://www.google.com', 'http://stackoverflow.com') 

corpi <- mclapply(urls, function(url) {
    html=getURL(url, followlocation=T)  
    doc=htmlParse(html,asText=T)
    return(xpathSApply(doc,"//p",xmlValue))
}, mc.cores=2)

这里还有 foreach 和 doMC:

library(RCurl)  
library(XML)  
library(doMC)
registerDoMC(cores=2)

urls <- c('http://www.google.com', 'http://stackoverflow.com') 

corpi <- foreach(url=urls, .combine=c) %dopar% {
    html=getURL(url, followlocation=T)  
    doc=htmlParse(html,asText=T)
    return(xpathSApply(doc,"//p",xmlValue))
}

如果您不熟悉 apply 函数,Foreach 可能会更容易使用。两者都可以在 OS X 和 Linux 上运行,但不能在 Windows 上运行。

【讨论】:

  • 我尝试了使用 foreach 的 doMC 以及使用 foreach 的 doParallel。我没有放 registerDoMC(cores=2),而是放了 registerDoMC(10)。当我尝试使用 3000 多个链接中的前 100 个链接时,它运行良好。但是当我在整个过程中运行它时,我得到一个错误“进程已经分叉,你不能安全地使用这个 CoreFoundation 功能。你必须执行()。”是因为我没有在 registerDoMC 中使用 cores=2 吗?
  • 我认为不是核心数。我从未在 OS X 上尝试过,但这里r.789695.n4.nabble.com/… 他们建议从命令行运行 R 而不是使用 GUI。
【解决方案2】:

正确的做法是执行并发请求。看一眼: ?getURIAsynchronous http://www.omegahat.org/RCurl/concurrent.html 然而,这种方法并不总是有效,但值得一试。

library(RCurl)

urls = c('http://stackoverflow.com/questions/22087072/parallel-computing-using-foreach',
         'http://www.omegahat.org/RCurl/FAQ.html', 
         'http://www.omegahat.org/RCurl/RCurlJSS.pdf')

opts = list(timeout = 1, maxredirs = 2,
            verbose = FALSE, followLocation = TRUE)

ls_uris <- list()
for(i in seq_along(urls)){
  print(i)
  ls_uris[[i]] <- getURIAsynchronous(urls[[i]], .opts=opts)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 2020-09-22
    • 2018-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多