首页 > 解决方案 > 使用 rvest 和 for 循环进行高效抓取

问题描述

我正在尝试使用 rvest 进行大量辩论。辩论在不同的网页上进行,我从搜索结果中收集这些网页的网址。有超过 1000 页的搜索结果,有 20,000 页的辩论(即 20,000 个 url)。

我目前的方法成功地从辩论页面中抓取了我需要的数据,但是,对于超过 20 页的搜索结果(即只有 20,000 个 URL 中的 400 个),处理需要很长时间。

我目前正在使用一个 forloop,它遍历我的 url 列表并用我需要的内容刮取 5 个 html 节点(见下文)。这将为我正在抓取的每个内容节点创建一个向量,然后我将其组合成一个数据框以进行分析。我认为这种方法意味着我为我需要的不同 html 节点分别调用每个网页 5 次。

有什么办法可以更有效地刮这个吗?我确信有一种方法可以做到这一点,这样它就可以在一次调用每个 url 时刮掉所有 5 个节点,而不是迭代 5 次。此外,是否可以在 for 循环中动态填充数据帧,而不是存储 5 个不同的向量。另外,也许我可以使用并行处理同时抓取多个网址?我很难过。

#create empty
speakerid <- c()
parties <- c()
contributions <- c()
titles <- c()
debatedates <- c()

#for loop to scrape relevant content
for(i in debate_urls$url) { 

  debate_urls <- read_html(i)
  speaker <- debate_urls %>% html_nodes(".debate-speech__speaker__name") %>% html_text("")
  speakerid = append(speakerid, speaker)

  debate_urls <- read_html(i)
  party <- debate_urls %>% html_nodes(".debate-speech__speaker__position") %>% html_text("")
  parties = append(parties, party)

  debate_urls <- read_html(i)
  contribution <- debate_urls %>% html_nodes(".debate-speech__speaker+ .debate-speech__content") %>% html_text("p")
  contributions = append(contributions, contribution)

  debate_urls <- read_html(i)
  title <- debate_urls %>%
    html_node(".full-page__unit h1") %>%
    html_text()
  titles = append(titles, rep(title,each=length(contribution)))

  debate_urls <- read_html(i)
  debatedate <- debate_urls %>%
    html_node(".time") %>%
    html_text("href")
  debatedates = append(debatedates, rep(debatedate,each=length(contribution)))
  }

debatedata <- data.frame(Title=titles, Date=debatedates,Speaker=speakerid,Party=parties,Utterance=contributions)

注意:debate_urls 是辩论页面的 url 列表。

任何有关如何更有效地完成任何部分的帮助将不胜感激!

标签: rfor-loopweb-scrapingrvest

解决方案


有一件事肯定是低效的,那就是不断增长的向量。您知道它们有多长 ( length(debate_urls$url)),因此您可以提前设置向量:

n <- length(debate_urls$url)
speakerid <- character(n)
parties <- character(n)
contributions <- character(n)
titles <- character(n)
debatedates <- character(n)

然后你的for循环这样做:

for(idx in seq_along(debate_urls$url)){
    i <- debate_urls$url[idx]

    debate_urls <- read_html(i)
    speaker <- debate_urls %>% html_nodes(".debate-speech__speaker__name") %>% html_text("")
    speakerid[idx] <- speaker
    ...
}

我不太确定的是,与抓取时间相比,这是否有很大的影响。


推荐阅读