首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >R中的昏迷web爬虫(带rvest)

R中的昏迷web爬虫(带rvest)
EN

Stack Overflow用户
提问于 2015-10-01 17:03:26
回答 3查看 1.3K关注 0票数 2

我最近在R中发现了rvest包,并决定尝试一些web抓取。

我在一个函数中写了一个小的网络爬虫,这样我就可以通过管道来清理它,等等。

对于较小的url列表(例如1-100),该函数工作得很好,但是当使用较大的列表时,该函数会在某一时刻挂起。似乎其中一个命令正在等待响应,但似乎没有得到响应,也没有导致错误。

代码语言:javascript
运行
复制
urlscrape<-function(url_list) {

library(rvest)
library(dplyr)
assets<-NA
price<-NA
description<-NA
city<-NA
length(url_list)->n
pb <- txtProgressBar(min = 0, max = n, style = 3)


for (i in 1:n) {
#scraping for price#
try( {read_html(url_list[i]) %>% html_node(".price span") %>% html_text()->price[i]}, silent=TRUE)

#scraping for city#
try( {read_html(url_list[i]) %>% html_node(".city") %>% html_text()->city[i]}, silent=TRUE)

#scraping for description#
try( {read_html(url_list[i]) %>% html_nodes("h1") %>% html_text() %>% paste(collapse=" ") ->description[i]}, silent=TRUE)

#scraping for assets#
try( {read_html(url_list[i]) %>% html_nodes(".assets>li") %>% html_text() %>% paste(collapse=" ") ->assets[i]}, silent=TRUE)

Sys.sleep(2)
setTxtProgressBar(pb, i)
}


Sys.time()->time
print("")
paste("Finished at",time) %>% print()
print("")
return(as.data.frame(cbind(price,city,description,assets)) )
}

(1)在不知道确切问题的情况下,我在rvest包中寻找超时选项,但无济于事。然后我尝试使用httr包中的超时选项(结果仍然是控制台挂起)。对于".price“,它将变成:

代码语言:javascript
运行
复制
content(GET(url_list[i], timeout=(10)), timeout=(10), as="text") %>% read_html() %>% html_node(".price span") %>% html_text()->price[i]}, silent=TRUE)

我想到了其他解决方案,并试图实现它们,但它不起作用。

(2)使用setTimeLimit实现时间限制:

代码语言:javascript
运行
复制
length(url_list)->n
pb <- txtProgressBar(min = 0, max = n, style = 3)
setTimeLimit(elapsed=20)

(3)测试url成功,第四次刮擦后c增加:

代码语言:javascript
运行
复制
for (i in 1:n) {
        while(url_success(url_list[i])==TRUE & c==i) {

所有这些都不起作用,因此当url列表很大时,函数仍然挂起。问:为什么控制台会挂起,如何解决?感谢您的阅读。

EN

回答 3

Stack Overflow用户

发布于 2017-02-05 19:19:28

不幸的是,上面的解决方案对我都不起作用。一些URL冻结了R脚本,不管它是否与read_html(..)从rvest,GET(..),getUrl(..)或getUrlContent(..)来自RCurl。

对我来说唯一有效的解决方案是R.utils的evalWithTimeout和tryCatchBlock的组合:

代码语言:javascript
运行
复制
# install.packages("R.utils")
# install.packages("rvest")
library(R.utils)
library(rvest)
pageIsBroken = FALSE

url = "http://www.detecon.com/de/bewerbungsformular?job-title=berater+f%c3%bcr+%e2%80%9cdigital+transformation%e2%80%9d+(m/w)"

page = tryCatch(

  evalWithTimeout({ read_html(url, encoding="UTF-8") }, timeout = 5),

  error = function(e) {
    pageIsBroken <<- TRUE; 
    return(e)
  }
)

if (pageIsBroken) {
  print(paste("Error Msg:", toString(page)))
}

rrscriptrvestrcurlfreezingweb-scrapingconnection-timeoutread-htmlevalwithtimeout

票数 2
EN

Stack Overflow用户

发布于 2016-02-10 16:16:54

解决此问题的一种简单方法是重复http请求,直到收到服务器的成功响应:

代码语言:javascript
运行
复制
for (i in 1:n) {
    repeat {
          html <- try(read_html(url_list[i]),silent=TRUE)
          if(class(html) != "try-error") break
        }
    html %>% html_node(".price span") %>% html_text()->price[i]
}
票数 1
EN

Stack Overflow用户

发布于 2016-07-09 21:40:41

我遇到了同样的问题(read_html在一些网页后停滞)。在我的例子中,使用RCurl的getURL来获取网页是有帮助的。在你可以尝试这个之前,先结合这篇文章:

代码语言:javascript
运行
复制
repeat {
  rawhtml <- try(getURL(link[i], .encoding="ISO-8859-1", .mapUnicode = F),silent=TRUE)
  if(class(rawhtml) != "try-error") break
}

html<-read_html(rawhtml)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32883512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档