Rvest:为多个html链接建立队列

问题描述

我目前正在网上搜刮新闻杂志,但不幸的是,我对如何建立工作队列一无所知。我只能在一页上抓取所有文章内容,但是我想要一个队列,该队列自动对其余文章执行相同的操作。

library(rvest)
library(tidyverse)
library(data.table)
library(plyr)
library(writexl)


map_dfc(.x = c("em.entrylist__title","time.entrylist__time"),.f = function(x) {read_html("https://www.sueddeutsche.de/news/page/1?search=Corona&sort=date&all%5B%5D=dep&all%5B%5D=typ&all%5B%5D=sys&time=2020-07-19T00%3A00%2F2020-07-27T23%3A59&startDate=27.07.2020&endDate=01.08.2020") %>% 
            html_nodes(x) %>% 
            html_text()}) %>%
  bind_cols(url = read_html("https://www.sueddeutsche.de/news/page/1?search=Corona&sort=date&all%5B%5D=dep&all%5B%5D=typ&all%5B%5D=sys&time=2020-07-19T00%3A00%2F2020-07-27T23%3A59&startDate=27.07.2020&endDate=01.08.2020") %>% 
              html_nodes("a.entrylist__link") %>% 
              html_attr("href")) %>% 
  setNames(nm = c("title","time","url")) -> temp

map_df(.x = temp$url[1:50],.f = function(x){tibble(url = x,text = read_html(x) %>% 
                                 html_nodes("#article-app-container > article > div.css-isuemq.e1lg1pmy0 > p:nth-child(n)") %>% 
                                 html_text() %>% 
                                 list
       )}) %>% 
  unnest(text) -> foo

foo

X2 <- ddply(foo,.(url),summarize,Xc=paste(text,collapse=","))

final <- merge(temp,X2,by="url") 

在这种情况下,我有30页充满文章,但是我的脚本仅支持刮取一页。 在页面之间唯一改变的是页面编号(https://www.sueddeutsche.de/news/**page/1**?search=...

如果您可以提示我如何将所有页面立即包含在队列中,我将不胜感激。非常感谢:)

解决方法

以数据框形式的队列如何为您工作?
以下建议更具通用性,因此它将在特定的用例之外起作用。您可以随时添加更多网址以进行抓取,但是由于dplyr::distinct,仅保留 new 网址。
(我已经启动队列来保存要抓取的前5页,如果您在DOM上找到链接,则可以立即添加或动态添加更多内容。)

library(dplyr)
library(lubridate)

queue <- tibble(
  url = paste0("https://www.sueddeutsche.de/news/page/",1:5,"?search=Corona&sort=date&all%5B%5D=dep&all%5B%5D=typ&all%5B%5D=sys&time=2020-07-19T00%3A00%2F2020-07-27T23%3A59&startDate=27.07.2020&endDate=01.08.2020"),scraped_time = lubridate::NA_POSIXct_
)

results <- list()

while(length(open_rows <- which(is.na(queue$scraped_time))) > 0) {
  i <- open_rows[1]
  url <- queue$url[i]

  [...]
  results[[url]] <- <YOUR SCRAPING RESULT>
  
  queue$scraped_time[i] <- lubridate::now()
  
  if (<MORE PAGES TO QUEUE>) {
    queue <- queue %>%
      tibble::add_row(url = c('www.spiegel.de','www.faz.de')) %>%
      arrange(desc(scraped_time)) %>%
      distinct(url,.keep_all = T)
  }
}