处理来自 read_html 的空网页的错误响应

Handling error response to empty webpage from read_html

尝试抓取网页标题,但 运行 遇到名为 "tweg.com"

的网站的问题
library(httr)
library(rvest)
page.url <- "tweg.com"
page.get <- GET(page.url) # from httr
pg <- read_html(page.get) # from rvest
page.title <- html_nodes(pg, "title") %>% 
  html_text() # from rvest

read_html 停止并显示一条错误消息:"Error: Failed to parse text"。 查看 page.get$content,发现它是空的 (raw(0))。

当然,可以写一个简单的检查来考虑这一点,避免使用 read_html 进行解析。然而,感觉一个更优雅的解决方案是从 read_html 取回一些东西,然后基于它 return 一个空的页面标题(即“”)。尝试将 "options" 传递给 read_html,例如 RECOVER、NOERROR 和 NOBLANKS,但没有成功。任何想法如何从 read_html 取回 "empty page" 响应?

您可以使用 tryCatch 来捕获错误,特别是 return 某些东西(如果您只想 return 错误并继续,那么 try(read_html('http://tweg.com'), silent = TRUE) 就可以了)。您需要传递 tryCatch 一个函数,以便在捕获到错误时 return 执行什么操作,您可以根据需要构造它。

library(rvest)


tryCatch(read_html('http://tweg.com'), 
         error = function(e){'empty page'})    # just return "empty page"
#> [1] "empty page"

tryCatch(read_html('http://tweg.com'), 
         error = function(e){list(result = 'empty page', 
                                  error = e)})    # return error too
#> $result
#> [1] "empty page"
#> 
#> $error
#> <Rcpp::exception in eval(substitute(expr), envir, enclos): Failed to parse text>

purrr 包还包含两个函数 possiblysafely,它们做同样的事情,但接受更灵活的函数定义。请注意,它们是副词,因此 return 仍然是必须调用的函数,这就是为什么 URL 在调用后的括号中。

library(purrr)

possibly(read_html, 'empty page')('http://tweg.com')
#> [1] "empty page"

safely(read_html, 'empty page')('http://tweg.com')
#> $result
#> [1] "empty page"
#> 
#> $error
#> <Rcpp::exception in eval(substitute(expr), envir, enclos): Failed to parse text>

典型的用法是将结果函数映射到 URLs 的向量中:

c('http://tweg.com', 'http://wikipedia.org') %>% 
    map(safely(read_html, 'empty page'))
#> [[1]]
#> [[1]]$result
#> [1] "empty page"
#> 
#> [[1]]$error
#> <Rcpp::exception in eval(substitute(expr), envir, enclos): Failed to parse text>
#> 
#> 
#> [[2]]
#> [[2]]$result
#> {xml_document}
#> <html lang="mul" dir="ltr" class="no-js">
#> [1] <head>\n  <meta charset="utf-8"/>\n  <title>Wikipedia</title>\n  <me ...
#> [2] <body id="www-wikipedia-org">\n<h1 class="central-textlogo" style="f ...
#> 
#> [[2]]$error
#> NULL