【问题标题】:Scraping <li> elements with Rvest使用 Rvest 抓取 <li> 元素
【发布时间】:2018-10-04 15:36:53
【问题描述】:

早上好,

我刚开始使用 R 进行抓取,我很难以有用的方式从网页中抓取元素列表。

这是我的脚本

library(rvest)

url <- read_html("https://www.pole-emploi.fr/annuaire/provins-77070")

webpage <- url %>%
  html_nodes('.zone') %>%
  html_text()
webpage
 

当我运行脚本时,所有元素看起来都挤在一起,中间没有任何空格,这是可以理解的,因为每个项目都包含在一个单独的

  • 标签。
     [1] "77114GouaixHerméNoyen-sur-SeineVilliers-sur-Seine"                                                                                                                                 
     [2] "77118BalloyBazoches-lès-BrayGravon"     
    

    我希望它们像这样(或用逗号分隔)

    [1] "77114 Gouaix Hermé Noyen-sur-Seine Villiers-sur-Seine"                                                                                                                                 
    [2] "77118 Balloy Bazoches-lès-Bray Gravon"
    

    或者在整洁的格式上更好

     Postal City
     77114  Gouaix
     77114  Hermé
     77114  Noyen-sur-Seine
     77114  Villiers-sur-Seine
    

    我试图在页面中找到其他选择器或 Xpath,但没有成功。我最多只能选择列表中的一个元素。

    任何帮助将不胜感激。

    提前致谢。

  • 【问题讨论】:

      标签: r rvest


      【解决方案1】:

      每个列表元素如下所示(为简洁起见被截断):

      <li class="zone">\n<span class="code-postal">77114</span><ul>\n<li>Gouaix</li>\n<li>Hermé</li>\n ...
      

      因此,每个节点都有一组看起来统一的子节点。我们可以定位嵌套的&lt;ul&gt; 中的&lt;span&gt;&lt;li&gt; 元素来获得你想要的:

      library(rvest)
      library(tidyverse)
      
      pg <- read_html("https://www.pole-emploi.fr/annuaire/provins-77070")
      
      html_nodes(pg, ".zone") %>% 
        map_df(~{
          data_frame(
            postal = html_node(.x, "span") %>% html_text(trim=TRUE),
            city = html_nodes(.x, "ul > li") %>% html_text(trim=TRUE)
          )
        }) 
      ## # A tibble: 95 x 2
      ##    postal city                 
      ##    <chr>  <chr>                
      ##  1 77114  Gouaix               
      ##  2 77114  Hermé                
      ##  3 77114  Noyen-sur-Seine      
      ##  4 77114  Villiers-sur-Seine   
      ##  5 77118  Balloy               
      ##  6 77118  Bazoches-lès-Bray    
      ##  7 77118  Gravon               
      ##  8 77126  Châtenay-sur-Seine   
      ##  9 77126  Égligny              
      ## 10 77134  Les Ormes-sur-Voulzie
      ## # ... with 85 more rows
      

      具有显式匿名函数的 tidyverse 方法(与 .x 通过公式函数相比):

      html_nodes(pg, ".zone") %>% 
        map_df(function(x) {
          data_frame(
            postal = html_node(x, "span") %>% html_text(trim=TRUE),
            city = html_nodes(x, "ul > li") %>% html_text(trim=TRUE)
          )
        }) 
      

      而且,一个纯基础 R 版本:

      elements <- html_nodes(pg, ".zone")
      lapply(elements, function(x) {
        data.frame(
          postal = html_text(html_node(x, "span"), trim=TRUE),
          city = html_text(html_nodes(x, "ul > li"), trim=TRUE),
          stringsAsFactors = FALSE
        )
      }) -> tmp
      
      Reduce(rbind.data.frame, tmp)
      
      # or
      
      do.call(rbind.data.frame, tmp)
      

      【讨论】:

      • 非常感谢!那非常有用。还有一个问题,html_node(.x, "span") 中的 .x 是一个占位符,用于将“.zone”转发到这个嵌套的 html_node 元素吗?再次感谢。
      • 我添加了 2 个额外的解决方案,希望能帮助展示正在发生的事情。主要示例中的“~{}”是一个 tidyverse purrr“公式函数”,它有一个可以使用的隐式变量名称 .x(或只是 .)。它是帮助代码简洁的语法糖,但就像 Scala 代码中的 _ 一样,它只是“突然弹出一个变量”,乍一看肯定令人困惑。
      • 非常感谢添加的 cmets。这一点现在很清楚了。
      猜你喜欢
      • 2021-12-31
      • 2020-07-18
      • 1970-01-01
      • 2023-01-07
      • 2020-08-15
      • 1970-01-01
      • 2020-07-18
      • 2019-02-17
      • 2017-06-26
      相关资源
      最近更新 更多