【问题标题】:Webscraping with loop带循环的网页抓取
【发布时间】:2019-11-18 10:05:30
【问题描述】:

我正在尝试使用循环函数从网站上抓取一些文本,但我的循环函数不会继续选择矢量列表中的下一项。感谢任何有用的建议。谢谢

library(rvest)
library(xml2)


ID <- c(1:2)
Land <- c('Afghanistan','Ägypten')
url <- c('afghanistan', 'aegypten') 
Text <- (NA)

data <- data.frame(ID, Land, Text)

for(i in url) {
  nam <- paste("https://www.reporter-ohne-grenzen.de", i, sep = "/")
  assign(nam, i)

  webpage <- read_html(paste0(nam, i))
  data$Text <- i <- webpage %>% html_nodes('div.text') %>% .[[1]] %>% html_text() 
}

嗯,不知道我是否把我的问题说清楚了。这是我想要的数据输出的一个例子。

library(rvest)
library(xml2)

ID <- c(1:2)
Land <- c('Afghanistan','Ägypten')
url <- c('afghanistan', 'aegypten') 
Text <- (NA)

data <- data.frame(ID, Land, Text)


afghanistan <- 'https://www.reporter-ohne-grenzen.de/afghanistan'
afghanistan <- read_html(afghanistan)
afghanistan <- html_nodes(afghanistan,'div.text')
afghanistan <- html_text(afghanistan)[[1]]

aegypten <- 'https://www.reporter-ohne-grenzen.de/aegypten'
aegypten <- read_html(aegypten)
aegypten <- html_nodes(aegypten,'div.text')
aegypten <- html_text(aegypten)[[1]]

# desired data output
data$Text <- c(afghanistan, aegypten)

我不想在 180 个国家/地区重复这些行。

aegypten <- 'https://www.reporter-ohne-grenzen.de/aegypten'
aegypten <- read_html(aegypten)
aegypten <- html_nodes(aegypten,'div.text')
aegypten <- html_text(aegypten)[[1]]

解决方案如下:

library(rvest)
library(xml2)

ID <- c(1:4) 
Land <- c('Afghanistan','Ägypten','Deutschland','Italien')
Url <- c('afghanistan', 'aegypten','deutschland','italien') 
Text <- NA

data <- data.frame(ID, Land, Text)
website <- 'https://www.reporter-ohne-grenzen.de'

for (i in ID) {
  country <- Url[i]

  html_url <- paste(website,country,sep='/')
  output <- read_html(html_url)
  output <- html_nodes(output,'div.text')
  output <- html_text(output)[[1]]

  data$Text[i] <- output
}

【问题讨论】:

  • 你为什么使用assign?变量nam应该足够用在read_html中了,为什么还要加上i。我建议使用sapplylapply,因为这样您就可以在列表中获得结果,然后可以将其取消列出并从中创建一个data.frame。

标签: r loops web-scraping rvest xml2


【解决方案1】:

尽管 for 循环非常方便,但您通常通过创建可以迭代的函数来解决 R 中的迭代问题。

对于这个例子,我们可以将你的 for 循环放在一个函数中,然后使用 purrr 和函数 map() 或者在这种情况下使用 dplyrmutate() 中的子函数 map_character() 来存储文本产生一列。

library(rvest)
#> Loading required package: xml2
library(xml2)
library(tidyverse)

ID <- c(1:2)
Land <- c('Afghanistan','Ägypten')
url <- c('afghanistan', 'aegypten') 
Text <- (NA)

data <- data.frame(ID, Land, url, Text)

read_country <- function(country_url){

nam <- paste0("https://www.reporter-ohne-grenzen.de/", country_url)

webpage <- read_html(paste0(nam))

webpage %>% html_nodes('div.text') %>% .[[1]] %>% html_text() 

}

data <- data %>% 
    mutate(Text = map_chr(url, read_country))

reprex package (v0.3.0) 于 2019 年 11 月 18 日创建

【讨论】:

  • 啊,我不知道。只是认为它可以更容易地阅读函数返回的内容。实际上它确实有效(我使用reprex 包),因为可以在 URL 中使用国家名称,然后重定向到正确的 url,例如 reporter-ohne-grenzen.de/Ägypten 变为 reporter-ohne-grenzen.de/aegypten。但我已经改变了它,使它更明确。
【解决方案2】:

使用purrr函数和rvest,我们可以做到

library(purrr)
library(rvest)

data$Text <- map(paste0("https://www.reporter-ohne-grenzen.de/", url),
             ~.x %>% 
                read_html %>% 
                html_nodes('div.text') %>%
                html_text %>% .[[1]]) %>% flatten_chr()

数据

ID <- c(1:2)
Land <- c('Afghanistan','Ägypten')
url <- c('afghanistan', 'aegypten') 
Text <- (NA)
data <- data.frame(ID, Land, Text)

【讨论】:

    猜你喜欢
    • 2017-08-06
    • 2021-04-13
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多