【问题标题】:using rvest and purrr::map_df to build a dataframe: dealing with multiple-element tags使用 rvest 和 purrr::map_df 构建数据框:处理多元素标签
【发布时间】:2023-12-05 11:10:01
【问题描述】:

(基于我自己的问题及其@astrofunkswag here 的回答)

我正在使用rvest 抓取网页,并使用purrr::map_df 将收集的数据转换为数据框。我遇到了map_df 仅选择具有多个元素的html标签的第一个元素的问题。理想情况下,我希望在结果数据框中捕获标签的所有元素,并回收具有较少元素的标签。

取以下代码:

library(rvest)
library(tidyverse)

urls <- list("https://en.wikipedia.org/wiki/FC_Barcelona",
             "https://en.wikipedia.org/wiki/Rome")
h <- urls %>% map(read_html)

out <- h %>% map_df(~{
  a <- html_nodes(., "#firstHeading") %>% html_text()
  b <- html_nodes(., ".toctext") %>% html_text()

  a <- ifelse(length(a) == 0, NA, a)
  b <- ifelse(length(b) == 0, NA, b)

  df <- tibble(a, b)
})
out

产生以下输出:

> out
# A tibble: 2 x 2
  a            b        
  <chr>        <chr>    
1 FC Barcelona History  
2 Rome         Etymology
> 

这个输出是不需要的,因为它只包含与b 对应的标签的第一个元素。在源网页中,与b 关联的元素是网页的字幕。所需的输出或多或少是这样的:

  a            b        
  <chr>        <chr>    
1 FC Barcelona History  
2 FC Barcelona  1899–1922: Beginnings  
3 FC Barcelona 1923–1957: Rivera, Republic and Civil War  
.
.
6 Rome         Etymology
7 Rome         History
8 Rome         Earliest history
.
.
> 

【问题讨论】:

    标签: r rvest purrr


    【解决方案1】:

    来自?ifelse

    ifelse 返回一个与 test 形状相同的值

    例如,见

    ifelse(FALSE, 20, 1:5)
    #[1] 1
    

    由于length(FALSE) 为1,因此只选择1:5 的第一个值为1。

    同样,当你在做的时候

    ifelse(length(a) == 0, NA, a)
    

    length(length(a) == 0) 为 1,因此仅返回 a 的第一个值。

    在这种情况下,我们可以使用if 而不是ifelse,因为我们只有一个元素需要检查,因为

    if(FALSE) 20 else 1:5 #returns
    #[1] 1 2 3 4 5
    

    所以它会通过做给你输出

    library(tidyverse)
    library(rvest)
    
    h %>% map_df(~{
       a <- html_nodes(., "#firstHeading") %>% html_text()
       b <- html_nodes(., ".toctext") %>% html_text()
       a <- if (length(a) == 0) NA else a
       b <- if (length(b) == 0) NA else b
      tibble(a,b)
    }) 
    
    
    #    a            b                                        
    #   <chr>        <chr>                                    
    # 1 FC Barcelona History                                  
    # 2 FC Barcelona 1899–1922: Beginnings                    
    # 3 FC Barcelona 1923–1957: Rivera, Republic and Civil War
    # 4 FC Barcelona 1957–1978: Club de Fútbol Barcelona      
    # 5 FC Barcelona 1978–2000: Núñez and stabilization       
    # 6 FC Barcelona The Dream Team era                       
    # 7 FC Barcelona 2000–2008: Exit Núñez, enter Laporta     
    # 8 FC Barcelona 2008–2012: Guardiola era                 
    # 9 FC Barcelona 2014–present: Bartomeu era               
    #10 FC Barcelona Support                                  
    # … with 78 more rows
    

    【讨论】:

    • 太棒了。谢谢!