【问题标题】:make concurrent RCurl GET requests for set of URLs对一组 URL 发出并发 RCurl GET 请求
【发布时间】:2017-03-06 05:44:38
【问题描述】:

我编写了一个函数来使用 RCurl 来获取缩短 URL 重定向列表(bit.ly、t.co 等)的有效 URL,并在有效 URL 定位文档时处理错误(PDF 倾向于抛出“ curlPerform 出错...在字符串中嵌入 nul。")

如果可能的话,我想让这个函数更有效(同时将它保留在 R 中)。正如所写的那样,对于不缩短一千个或更多 URL 的运行时间非常长。

?getURI 告诉我们,默认情况下,当 url 向量的长度大于 1 时,getURI/getURL 会变为异步的。但是我的表现似乎完全是线性的,大概是因为sapply 把事情变成了一个大的 for 循环并且并发丢失了。

无论如何我可以加快这些请求的速度吗?修复“嵌入式 nul”问题的额外功劳。

require(RCurl)

options(RCurlOptions = list(verbose = F, followlocation = T,
                        timeout = 500, autoreferer = T, nosignal = T,
                        useragent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2)"))

# find successful location (or error msg) after any redirects
getEffectiveUrl <- function(url){ 
  c = getCurlHandle()
  h = basicHeaderGatherer()
  curlSetOpt( .opts = list(header=T, verbose=F), curl= c, .encoding = "CE_LATIN1")
  possibleError <- tryCatch(getURI( url, curl=c, followlocation=T, 
                                    headerfunction = h$update, async=T),
                            error=function(e) e)  
  if(inherits(possibleError, "error")){
    effectiveUrl <- "ERROR_IN_PAGE" # fails on linked documents (PDFs etc.)
  } else { 
    headers <- h$value()
    names(headers) <- tolower(names(headers)) #sometimes cases change on header names?
    statusPrefix <- substr(headers[["status"]],1,1) #1st digit of http status
    if(statusPrefix=="2"){ # status = success
      effectiveUrl <- getCurlInfo(c)[["effective.url"]]
    } else{ effectiveUrl <- paste(headers[["status"]] ,headers[["statusmessage"]]) } 
  }
  effectiveUrl
}

testUrls <- c("http://t.co/eivRJJaV4j","http://t.co/eFfVESXE2j","http://t.co/dLI6Q0EMb0",
              "http://www.google.com","http://1.uni.vi/01mvL","http://t.co/05Mz00DHLD",
              "http://t.co/30aM6L4FhH","http://www.amazon.com","http://bit.ly/1fwWZLK",
              "http://t.co/cHglxQkz6Z") # 10th URL redirects to content w/ embedded nul
system.time(
  effectiveUrls <- sapply(X= testUrls, FUN=getEffectiveUrl, USE.NAMES=F)
) # takes 7-10 secs on my laptop

# does Vectorize help? 
vGetEffectiveUrl <- Vectorize(getEffectiveUrl, vectorize.args = "url")
system.time(
  effectiveUrls2 <- vGetEffectiveUrl(testUrls)
) # nope, makes it worse

【问题讨论】:

  • 看起来你应该给getURIAsynchronous一个url向量。但是界面很繁琐,你如何重写作者来捕获标题而不是正文并不明显。您还应该设置 nobody = 1L 以避免检索正文(您不需要)

标签: r url-rewriting rcurl sapply


【解决方案1】:

我对 RCurl 和异步请求的体验很糟糕。 R 将完全冻结(尽管没有错误消息,CPU 和 RAM 没有峰值),只有并发 20 个请求。

我建议切换到 CURL 并使用 curl_fetch_multi() 函数。在我的情况下,它可以在一个池中轻松处理 50000 个 JSON 请求(在引擎盖下划分为子池)。 https://cran.r-project.org/web/packages/curl/vignettes/intro.html#async_requests

【讨论】:

    猜你喜欢
    • 2012-06-14
    • 2019-11-20
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 2014-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多