Цикл R с html_nodes (rvest) не захватывает все данные

Я хотел бы сделать цикл с html_node, чтобы поймать какое-то значение узлов (узлы без текста), то есть у меня есть некоторые значения

library(rvest)
country <- c("Canada", "US", "Japan", "China")

С этими значениями («Канада», «нас», ...) я выполнил цикл, который создает URL, вставляя каждое значение с помощью «", после этого с каждым новым html примените read_html (i) и последовательности кодов, чтобы наконец поймать узел с html_nodes ('a.page-link') -да! узел, а не текст, и сохраните этот html_nodes (...) как символ в data.frame (или может быть списком).

dff<- NULL
for ( i in country ) {
url<-paste0("https://en.wikipedia.org/wiki/",i)
page<- read_html(url) 
b <- page%>%
html_nodes ('h2.flow-title') %>%
html_nodes ('a.page-link') %>%
as.character()
dff<- data.frame(b)
}

Проблема в том, что этот код сохраняет данные только из последней страны, то есть запускает первую страну и получает html_nodes (сохраняет его), но при запуске следующей страны первые данные стираются и заменяются этой новой, и т. Д. , получив в качестве окончательного результата только данные из последней страны. Буду признателен с вашей помощью!


person AlphaScorpion    schedule 10.05.2018    source источник
comment
Вы получаете только последнее значение, потому что ваше значение b перезаписывается на каждой итерации, а dff<- data.frame(b) фактически не добавляет b к фрейму данных. Чего вы ждете от результата? Из вашего кода кажется, что вы получаете символьную строку с каждой итерации, почему бы не иметь вектор символов в качестве окончательного вывода?   -  person moho wu    schedule 10.05.2018


Ответы (1)


Как упоминалось в комментарии, эта строка: dff<- data.frame(b) перезаписывает dff на каждой итерации цикла. Решением является создание пустого списка и добавление данных в список.
В этом примере элементы списка названы в соответствии с запрашиваемой страной.

library(rvest)
country <- c("Canada", "US", "Japan", "China")

#initialize the empty list
dff<- list()

for ( i in country ) {
  url<-paste0("https://en.wikipedia.org/wiki/",i)
  page<- read_html(url) 
  b <- page%>%
    html_nodes ('h2.flow-title') %>%
    html_nodes ('a.page-link') %>%
    as.character()
#append new data onto the list
  dff[[i]]<- data.frame(b)
}

Для доступа к данным можно использовать dff $ Canada или lapply для обработки всего списка.

Примечание: я запустил ваш пример, который не дал результатов, лучше дважды проверьте идентификаторы узлов.

person Dave2e    schedule 10.05.2018
comment
В R не следует создавать пустые списки и добавлять в них новые элементы. Это заставит скребок использовать намного больше памяти, и, следовательно, он будет медленным. Если country были очень большими, это могло занять много времени. Вместо этого всегда объявляйте список размера N, в котором каждый элемент n пуст. Так что используйте вместо этого dff <- vector(mode = "list", length = length(country)). Все остальное может остаться прежним. См. глава 2 из The R Inferno, чтобы узнать больше о грехе выращивания объектов. - person ardaar; 02.11.2018