open.connection(x,“ rb”)中的错误:使用map_df时出现HTTP错误500

时间:2019-08-08 16:17:59

标签: r web-scraping try-catch rvest

尝试抓取新闻网站时出现错误。我检查了,网站页面32坏了。我想跳过该错误,并继续抓取其余网址。

我已经尝试过使用TryCatch函数来避免链接断开,但是由于我对R语言还很陌生,所以我不知道如何正确编写代码。我应该用该函数包装read_html吗?如果可以,怎么办?

url_silla <- 'https://lasillavacia.com/buscar/farc?page=%d'

map_df(0:573, function(i) {

  pagina <- read_html(sprintf(url_silla, i, '%s', '%s', '%s', '%s'))
  print(i)

  data.frame(titles = html_text(html_nodes(pagina,".col-sm-12 h3")),
             date = html_text(html_nodes(pagina, ".date.col-sm-3")),
             category = html_text(html_nodes(pagina, ".category.col-sm-9")),
             tags = html_text(html_nodes(pagina, ".tags.col-sm-12")),
             link = paste0("https://www.lasillavacia.com",str_trim(html_attr(html_nodes(pagina, "h3 a"), "href"))),
            stringsAsFactors=FALSE)
}) -> noticias_silla

这是错误。非常感谢您的帮助!

[1] 31
Error in open.connection(x, "rb") : HTTP error 500.
Called from: open.connection(x, "rb")

3 个答案:

答案 0 :(得分:1)

您可以将tryCatch构建到函数中,然后将该函数传递给map_dfr。将其设置为在发生错误时返回NULL,不会因map_dfr而中断数据帧的创建。

我建议您首先使用map进行尝试,这样您就可以调查一些索引如何返回所需的数据帧,而另一些返回NULL。无论哪种情况,finally参数都会显示索引。

library(dplyr)
library(purrr)
library(rvest)

url_silla <- 'https://lasillavacia.com/buscar/farc?page=%d'

read_page <- function(i) {
  tryCatch(
    {
      pagina <- read_html(sprintf(url_silla, i, '%s'))
      data.frame(titles = html_text(html_nodes(pagina,".col-sm-12 h3")),
                 date = html_text(html_nodes(pagina, ".date.col-sm-3")),
                 category = html_text(html_nodes(pagina, ".category.col-sm-9")),
                 tags = html_text(html_nodes(pagina, ".tags.col-sm-12")),
                 link = paste0("https://www.lasillavacia.com", trimws(html_attr(html_nodes(pagina, "h3 a"), "href"))),
                 stringsAsFactors=FALSE)
    },
    error = function(cond) return(NULL),
    finally = print(i)
  )
}

noticias <- map_dfr(30:33, read_page)
#> [1] 30
#> [1] 31
#> [1] 32
#> [1] 33

答案 1 :(得分:0)

下面的代码仅处理第31、32和33页。

我不会使用map_*来解决问题,我相信这可能会使事情变得比实际困难。我将使用标准的for循环,因为没有理由不这样做。

library(rvest)
library(stringr)
library(tidyverse)

url_silla <- 'https://lasillavacia.com/buscar/farc?page=%d'

pages <- 31:33
noticias_silla <- vector("list", length = length(pages))

for(i in pages){
  p <- sprintf(url_silla, i, '%s', '%s', '%s', '%s')
  pagina <- tryCatch(read_html(p),
                     error = function(e) e)
  print(i)
  if(inherits(pagina, "error")){
    noticias_silla[[i - pages[1] + 1]] <- list(page_num = i, page = p)
  }else{
    noticias_silla[[i - pages[1] + 1]] <- data.frame(titles = html_text(html_nodes(pagina,".col-sm-12 h3")),
                                           date = html_text(html_nodes(pagina, ".date.col-sm-3")),
                                           category = html_text(html_nodes(pagina, ".category.col-sm-9")),
                                           tags = html_text(html_nodes(pagina, ".tags.col-sm-12")),
                                           link = paste0("https://www.lasillavacia.com",str_trim(html_attr(html_nodes(pagina, "h3 a"), "href"))),
                                           stringsAsFactors=FALSE)
  }
}

lapply(noticias_silla, class)    noticias_silla[[1]]
noticias_silla[[2]]

#[[1]]
#[1] "data.frame"
#
#[[2]]
#[1] "list"
#
#[[3]]
#[1] "data.frame"    noticias_silla[[1]]
noticias_silla[[2]]

请注意,第二个列表成员是"list",而不是"data.frame"。这是发生错误的地方。

noticias_silla[[2]]
#$page_num
#[1] 32
#
#$page
#[1] "https://lasillavacia.com/buscar/farc?page=32"

答案 2 :(得分:0)

您可以使用purrr::possibly

url_silla <- 'https://lasillavacia.com/buscar/farc?page=%d'

library(tidyverse)
library(rvest)

map_df(0:573, possibly(~{

    pagina <- read_html(sprintf(url_silla, .x, '%s', '%s', '%s', '%s'))

    print(.x)

    data.frame(titles = html_text(html_nodes(pagina,".col-sm-12 h3")),
               date = html_text(html_nodes(pagina, ".date.col-sm-3")),
               category = html_text(html_nodes(pagina, ".category.col-sm-9")),
               tags = html_text(html_nodes(pagina, ".tags.col-sm-12")),
               link = paste0("https://www.lasillavacia.com",str_trim(html_attr(html_nodes(pagina, "h3 a"), "href"))),
               stringsAsFactors=FALSE)

}, NULL)) -> noticias_silla