R编程:rvest:用于循环覆盖数据的抓取

时间:2017-01-31 23:14:03

标签: r loops rvest

以下代码有效:

library(rvest)
library(plyr)

alaska <- c(1:49)

for (i in alaska) {

  url <- "http://www.50states.com/facts/alaska.htm"

  nodespath <- paste('//*[@id="content"]/div[1]/div[4]/ol/li[',i,']')

  alaskafacts <-  data.frame(facts =  url %>%   html() %>% 
                  html_nodes(xpath =nodespath) %>%   html_text())

 alaskafacts$nm <- i
 alaskafacts$facts <- alaskafacts$facts

 result <- rbind.fill(result,alaskafacts)
}

我会得到这个结果:

enter image description here

我知道循环正在运行,因为如果我将代码更改为:

alaska <- c(1:48)

我会得到这个结果:

enter image description here

我遇到的问题是循环写入自身。我期待49行事实 - 我猜测循环擦除了先前的事实,然后写了一个新的 - 最后一个事实将永远是data.frame中的事实。

我在这里找到了一个示例:How can I use a loop to scrape website data for multiple webpages in R?,上面发布的代码遵循示例中的代码。然后我引用了这个例子:here。我认为上面的代码也遵循它。

我在底部的rbind调用遵循我在SO上找到的两个类似的例子,但没有按预期保存。

有什么建议吗?

1 个答案:

答案 0 :(得分:2)

您需要在for循环之前预定义结果变量。目前每次循环结果都被覆盖。试试这个:

library(rvest)
library(plyr)

alaska <- c(1:49)
result<-data.frame()
for (i in alaska) {

  url <- "http://www.50states.com/facts/alaska.htm"
....

有一种更快的方法可以在不使用for循环的情况下提取所请求的信息(并且事先了解所需的长度)。 rvest被矢量化以允许在一个语句中提取所有节点:

library(rvest)

url <- "http://www.50states.com/facts/alaska.htm"
page<-url %>%   read_html()

resultsarray<-html_text(html_nodes(page, "ol.stripedList li"))
  # "ol.stripedList li" is the html code for the list hierarchical 
  # li (list element underneath) an ol (ordered list) of class "stripedList" 

resultsarray是一个包含49个事实的字符串数组,我将允许您将其转换为所需的数据帧。