如何在rvest中设置超时

Pet*_*r.k 5 timeout r rvest

一个简单的问题:此代码x <- read_html(url)挂起并读取页面无数秒。我不知道如何处理此问题,例如,通过设置一些最大响应时间。我可以使用try,catch和任何重试方法。但这只是挂起,没有任何反应。有人知道如何处理吗?

页面没有问题,有时会发生,而当我手动重试时,它会起作用。

use*_*745 10

你可以用read_htmlGET从功能httr

例如,如果您的原始代码是

library(rvest)
library(dplyr)

my_url <- "/sf/ask/3410545351/"
x <- my_url %>% read_html(.)
Run Code Online (Sandbox Code Playgroud)

那么你可以用

library(httr)

# Allow 10 seconds
my_url %>% GET(., timeout(10)) %>% read_html

# Allow 30 seconds
my_url %>% GET(., timeout(30)) %>% read_html
Run Code Online (Sandbox Code Playgroud)

例子

要进行测试,请尝试设置极短的超时时间(例如百分之一秒)

# Allow an unreasonably short amount of time so the request errors rather than hangs indefinitely

my_url %>% GET(., timeout(0.01)) %>% read_html

# Error in curl::curl_fetch_memory(url, handle = handle) : 
#   Timeout was reached: Resolving timed out after 10 milliseconds
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到更多示例

在循环中使用它(例如,如果超时,则跳到下一个)

尝试运行此代码。它假设您有多个(在这种情况下为 3 个)网址要访问(下面的第二个网址将在提供 html 之前延迟 3 秒 - 一种测试您正在寻找的功能的好方法)。我们将超时设置为 2 秒,因此我们知道它会失败。该tryCatch()函数将简单地执行您作为第二个参数放入的任何代码;在这种情况下,它将简单地分配“超时!” 到列表元素


my_urls <- c("/sf/ask/3410545351/",
             "http://httpbin.org/delay/3", # This url will delay 3 seconds
             "http://httpbin.org/delay/1") 

x <- list()

# Set timeout for 2 seconds (so second url will fail)
for (i in 1:length(my_urls)) {

  print(paste0("Scraping url number ", i))

  tryCatch(x[[i]] <- my_urls[i] %>% GET(., timeout(2)) %>% read_html,
           error = function(e) { x[[i]] <<- "Timed out!" } )
  
}
Run Code Online (Sandbox Code Playgroud)

现在我们检查输出 - 第一个和第三个站点返回内容,第二个超时

# > x
# [[1]]
# {xml_document}
# <html itemscope="" itemtype="http://schema.org/QAPage" class="html__responsive">
#   [1] <head>\n<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\n<title>r - how to set timeout ...
# [2] <body class="question-page unified-theme">\r\n    <div id="notify-container"></div>\r\n    <div id="custom ...
# 
# [[2]]
# [1] "Timed out!"
# 
# [[3]]
# {xml_document}
# <html>
# [1] <body><p>{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {}, \n  "headers": {\n    "Accept": ...


Run Code Online (Sandbox Code Playgroud)

显然,您可以将超时值设置为您想要的任何值。根据使用情况,30 - 60 秒可能是合理的。