使用 Rvest 抓取 <li> 元素

Cam*_*eno 3 r rvest

早上好,

\n

我是使用 R 进行抓取的新手,并且很难以有用的方式从网页中抓取元素列表。

\n

这是我的脚本

\n
library(rvest)\n\nurl <- read_html("https://www.pole-emploi.fr/annuaire/provins-77070")\n\nwebpage <- url %>%\n  html_nodes('.zone') %>%\n  html_text()\nwebpage\n \n
Run Code Online (Sandbox Code Playgroud)\n

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

  • 标签。

    \n

     [1] "77114GouaixHerm\xc3\xa9Noyen-sur-SeineVilliers-sur-Seine"                                                                                                                                 \n [2] "77118BalloyBazoches-l\xc3\xa8s-BrayGravon"     \n
    Run Code Online (Sandbox Code Playgroud)\n

    我想让它们像这样(或用逗号分隔)

    \n
    [1] "77114 Gouaix Herm\xc3\xa9 Noyen-sur-Seine Villiers-sur-Seine"                                                                                                                                 \n[2] "77118 Balloy Bazoches-l\xc3\xa8s-Bray Gravon"\n
    Run Code Online (Sandbox Code Playgroud)\n

    或者格式整洁更好

    \n
     Postal City\n 77114  Gouaix\n 77114  Herm\xc3\xa9\n 77114  Noyen-sur-Seine\n 77114  Villiers-sur-Seine\n
    Run Code Online (Sandbox Code Playgroud)\n

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

    \n

    任何帮助将不胜感激。

    \n

    提前致谢。

    \n
  • hrb*_*str 5

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

    \n\n
    <li class="zone">\\n<span class="code-postal">77114</span><ul>\\n<li>Gouaix</li>\\n<li>Herm\xc3\xa9</li>\\n ...\n
    Run Code Online (Sandbox Code Playgroud)\n\n

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

    \n\n
    library(rvest)\nlibrary(tidyverse)\n\npg <- read_html("https://www.pole-emploi.fr/annuaire/provins-77070")\n\nhtml_nodes(pg, ".zone") %>% \n  map_df(~{\n    data_frame(\n      postal = html_node(.x, "span") %>% html_text(trim=TRUE),\n      city = html_nodes(.x, "ul > li") %>% html_text(trim=TRUE)\n    )\n  }) \n## # A tibble: 95 x 2\n##    postal city                 \n##    <chr>  <chr>                \n##  1 77114  Gouaix               \n##  2 77114  Herm\xc3\xa9                \n##  3 77114  Noyen-sur-Seine      \n##  4 77114  Villiers-sur-Seine   \n##  5 77118  Balloy               \n##  6 77118  Bazoches-l\xc3\xa8s-Bray    \n##  7 77118  Gravon               \n##  8 77126  Ch\xc3\xa2tenay-sur-Seine   \n##  9 77126  \xc3\x89gligny              \n## 10 77134  Les Ormes-sur-Voulzie\n## # ... with 85 more rows\n
    Run Code Online (Sandbox Code Playgroud)\n\n

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

    \n\n
    html_nodes(pg, ".zone") %>% \n  map_df(function(x) {\n    data_frame(\n      postal = html_node(x, "span") %>% html_text(trim=TRUE),\n      city = html_nodes(x, "ul > li") %>% html_text(trim=TRUE)\n    )\n  }) \n
    Run Code Online (Sandbox Code Playgroud)\n\n

    并且,纯基础 R 版本:

    \n\n
    elements <- html_nodes(pg, ".zone")\nlapply(elements, function(x) {\n  data.frame(\n    postal = html_text(html_node(x, "span"), trim=TRUE),\n    city = html_text(html_nodes(x, "ul > li"), trim=TRUE),\n    stringsAsFactors = FALSE\n  )\n}) -> tmp\n\nReduce(rbind.data.frame, tmp)\n\n# or\n\ndo.call(rbind.data.frame, tmp)\n
    Run Code Online (Sandbox Code Playgroud)\n