循环从 R 中的维基百科抓取数据

Loop to scrape data from Wikipedia in R

我正在尝试提取有关 celebrity/notable 死亡的数据以供分析。维基百科关于重要死亡日期的 html 路径具有非常规则的结构。看起来像:

https://en.wikipedia.org/wiki/Deaths_in_"MONTH"_"YEAR"

例如,这个 link 导致了 2014 年 3 月的显着死亡。

https://en.wikipedia.org/wiki/Deaths_in_March_2014

我找到了我需要的列表的 CSS 位置“”#mw-content-text h3+ ul li”并成功提取了特定的 link。现在我'我正在尝试编写一个循环来遍历我选择的月份和任何年份。我认为这是一个非常简单的嵌套循环,但我在 2015 年测试它时遇到错误。

library(rvest)
data = data.frame()
 mlist = c("January","February","March","April","May","June","July","August",
              "September","October","November","December")

for (y in 2015:2015){
  for (m in 1:12){
    site = read_html(paste("https://en.wikipedia.org/wiki/Deaths_in_",mlist[m],
           "_",y,collapse=""))
    fnames = html_nodes(site,"#mw-content-text h3+ ul li")
    text = html_text(fnames)
    data = rbind(data,text,stringsAsFactors=FALSE)
      }
 }

当我注释掉这一行时:

data = rbind(data,text,stringsAsFactors=FALSE)

没有返回任何错误,显然与此位有关。我也发布了我的整个代码以供其他评论。这里的目标是循环很多年,然后关注年和月的分布。为此,我只需要保留死亡的年龄、月份和年份。

谢谢!

编辑:抱歉,它们在技术上是警告,而不是错误。我得到了超过 50 个,当我试图查看 "data" 时,它是一个巨大的混乱。

当我 运行 这段代码不是作为一个特定 URL 的循环时,它工作正常并且 returns 一个可读的输出。

site = read_html("https://en.wikipedia.org/wiki/Deaths_in_January_2015")
fnames = html_nodes(site,"#mw-content-text h3+ ul li")
text = html_text(fnames)

以下是该数据集中的几行:

text[1:5]
[1] "Barbara Atkinson, 88, British actress (Z-Cars).[1]"                                         
[2] "Staryl C. Austin, 94, American air force brigadier general.[2]"                             
[3] "Ulrich Beck, 70, German sociologist, heart attack.[3]"                                      
[4] "Fiona Cumming, 77, British television director (Doctor Who).[4]"                            
[5] "Eric Cunningham, 65, Canadian politician, Ontario MPP for Wentworth North (1975–1984).[5]"

我没能得到与你一样的错误,但我想我知道你想做什么。

我感觉这跟每个月的死亡人数不均有关

我建议这样做

mlist = c("January","February","March","April","May","June","July","August",
      "September","October","November","December")

for (y in 2015:2015){
  for (m in 1:12){
    site = read_html(paste("https://en.wikipedia.org/wiki/Deaths_in_",mlist[m],
                       "_",y,collapse=""))
    fnames = html_nodes(site,"#mw-content-text h3+ ul li")
    text = html_text(fnames)
    assign(mlist[m],text)
  }
}

这会为每个月的死亡人数创建一个角色列表。

另一种方法(为了以后在循环中加入它们更容易使用)是使用列表:

data = vector("list",12)
mlist = c("January","February","March","April","May","June","July","August",
      "September","October","November","December")

for (y in 2015:2015){
  for (m in 1:12){
    site = read_html(paste("https://en.wikipedia.org/wiki/Deaths_in_",mlist[m],
                       "_",y,collapse=""))
    fnames = html_nodes(site,"#mw-content-text h3+ ul li")
    text = html_text(fnames)
    data[[m]] = text
  }
}

就个人而言,我不喜欢在 R 中处理列表。但这似乎是最好的解决方法。

html_text(fnames) returns 一个数组。您的问题是尝试将数组附加到数据框上。
在附加之前尝试将变量 text 转换为数据框:

for (y in 2015:2015){
  for (m in 1:12){
    site = read_html(paste("https://en.wikipedia.org/wiki/Deaths_in_",mlist[m],
           "_",y,collapse=""))
    fnames = html_nodes(site,"#mw-content-text h3+ ul li")
    text = html_text(fnames)

    temp<-data.frame(text, stringsAsFactors = FALSE)

    data = rbind(data,temp)
    }
 } 

出于性能原因,这不是最佳技术。每次通过循环,都会重新分配数据帧的内存,这会降低性能,因为这是一次性事件并且请求数量有限,在这种情况下应该是可以管理的。