如何使用R从多个维基百科页面抓取数据?

时间:2020-04-26 01:14:23

标签: r web-scraping wikipedia

我对R中的数据抓取是陌生的,但是我想做以下事情。我有一个名人名单,celebs,我想从维基百科获取他们的生日。我知道如何针对每个名人,但我正在尝试使这一过程动起来。

celebs <- c("Tom Hanks", "Tim Cook", "Michael Bloomberg")

我执行以下操作以获取第一位名人Tom Hanks所需的信息。

library(rvest)

wiki <- read_html("https://en.wikipedia.org/wiki/Tom_Hanks")

birth_date <- wiki %>%
  html_nodes(xpath = '//*[@id="mw-content-text"]/div/table/tbody/tr[3]/td/text()') %>%
  html_text()

是否有一种无需手动编辑以上代码即可获取Tim CookMichael Bloomberg所需信息的方法?

1 个答案:

答案 0 :(得分:1)

欢迎来到。

要使用代码重复执行任何任务,您应该始终寻找建立循环的方法。在构建循环之前,应尝试构建循环的单个迭代。您几乎已经准备就绪,但缺少一些步骤。

首先,我们应该尝试对代码进行通用化,以便只需切换迭代器(名人)向量中的一个变量的值即可使其起作用。

person <- "Tom Hanks"

现在,使用该代码,我们需要通过代码创建Wikipedia链接。这里有两件事要考虑:

  1. 我们需要在人员姓名之前添加链接;
  2. 我们应该将“ Tom Hanks”中的空格替换为下划线

我们可以使用以下代码做到这一点:

link <- paste0("https://en.wikipedia.org/wiki/", 
               str_replace_all(person, " ", "_"))

这将创建正确的链接,我们可以将其用于后续步骤。现在,这只是迭代celebs向量的问题。有很多方法可以执行此操作,但是在R中,最合适的方法是使用sapply。为此,我们将创建一个匿名函数,该函数将使用person的名称作为输入,使用已编写的代码查询维基百科并提取其生日:

function(person) {
    link <- paste0("https://en.wikipedia.org/wiki/", 
                   str_replace_all(person, " ", "_"))

    wiki <- read_html(link)

    birth_date <- wiki %>%
        html_nodes(xpath = '//*[@id="mw-content-text"]/div/table/tbody/tr[3]/td/text()') %>%
        html_text()
    return(birth_date)
}

您现在可以在其周围包裹一个sapply结构:

birthdates <- sapply(celebs, function(person) {
    link <- paste0("https://en.wikipedia.org/wiki/", 
                   str_replace_all(person, " ", "_"))

    wiki <- read_html(link)

    birth_date <- wiki %>%
        html_nodes(xpath = '//*[@id="mw-content-text"]/div/table/tbody/tr[3]/td/text()') %>%
        html_text()
    return(birth_date)
})