【问题标题】:R error HTML is deprecated when scraping table from website从网站抓取表格时不推荐使用 R 错误 HTML
【发布时间】:2020-05-20 19:20:29
【问题描述】:

我正在尝试从网站上抓取表格:

我正在使用以下代码:


library("rvest")

url <- "http://sabap2.birdmap.africa/coverage/pentad/2945_3100"

population <- url %>%
  html() %>%
  html_nodes(xpath='//*[@id="coverage_species"]/div/div/table') %>%
  html_table()

但我收到以下错误:

Warning message:
'html' is deprecated.
Use 'xml2::read_html' instead.
See help("Deprecated") 

谁能建议使用 xml2 的正确方法? 我也不确定是否在 html_nodes 步骤中使用了正确的 xPath?

谢谢

【问题讨论】:

  • 这不是一个错误,只是一个友好的警告。如果您不想收到警告,请在代码中使用 read_html 而不是 html
  • @akrun 没错,但代码无论如何都不起作用,因为它是一个动态网页,需要一些低级工作才能抓取。
  • 我没有测试过,我的评论是基于警告本身
  • 可能需要硒
  • @akrun,不,可以通过文本解析来完成 - 请参阅我的答案

标签: r web-scraping rvest


【解决方案1】:

您要查找的表格是在页面加载到浏览器后从 Javascript 动态构建的。您可以使用字符串操作提取相关的 Javascript 片段并解析它们以在 R 中构建表格。

这与您收到的警告无关,它只是告诉您使用read_html() 而不是html(),因为read_html() 是执行类似工作的新功能,而html() 正在逐步淘汰.

url       <- "http://sabap2.birdmap.africa/coverage/pentad/2945_3100"
page      <- httr::content(httr::GET(url), "text")
json      <- strsplit(strsplit(page, "summarydata.addRows[(]")[[1]][2], "[)]")[[1]][1]
df        <- data.frame(rbind(jsonlite::fromJSON(json)), stringsAsFactors = FALSE)
lines     <- strsplit(page, "[\r\n]+")[[1]]
linelist  <- strsplit(grep("summarydata[.]addCol", lines, value = TRUE), "'")
names(df) <- sapply(linelist, `[`, 4)

这会在一个漂亮的数据框中给出结果:

df
#>        Year no cards 1 card 2 cards 3 cards 4 or more Pentads covered
#> 1  AllYears        0      0       0       0         1               1
#> 2      2020        0      0       0       1         0               1
#> 3      2019        0      0       0       0         1               1
#> 4      2018        0      0       0       0         1               1
#> 5      2017        0      0       0       0         1               1
#> 6      2016        0      0       0       0         1               1
#> 7      2015        0      0       0       0         1               1
#> 8      2014        0      0       0       0         1               1
#> 9      2013        0      0       0       0         1               1
#> 10     2012        0      0       0       0         1               1
#> 11     2011        0      0       0       0         1               1
#> 12     2010        0      0       0       0         1               1
#> 13     2009        0      0       0       0         1               1
#> 14     2008        0      0       0       0         1               1
#> 15     2007        0      0       0       0         1               1
#>    Pentads in area Total Cards (FP) Total species (FP)
#> 1                1              361                284
#> 2                1                3                 44
#> 3                1               18                158
#> 4                1               21                165
#> 5                1               51                172
#> 6                1               45                198
#> 7                1               25                178
#> 8                1               12                149
#> 9                1               26                165
#> 10               1               34                163
#> 11               1               46                189
#> 12               1               36                181
#> 13               1               22                146
#> 14               1               17                173
#> 15               1                5                131

附录

OP 已要求在页面上解析不同的表。可以用类似的方式完成,如下所示:

species_json <- strsplit(page, "carddataspeciesmonthly[.]addRows[(]")[[1]][2]
species_tab <- jsonlite::fromJSON(strsplit(species_json, "[)];")[[1]][1])
species_df <- as.data.frame(species_tab)
species_cols <- strsplit(page, "carddataspeciesmonthly[.]addColumn[(]")[[1]][-1]
names(species_df) <- sapply(strsplit(species_cols, "'"), `[`, 4)

生成的数据框太大,无法在此处显示,因此我将其显示为tibble

dplyr::as_tibble(species_df)
# A tibble: 284 x 20
   Ref   Common_group Common_species Genus Species Jan   Feb   Mar   Apr   May   Jun   Jul  
   <fct> <fct>        <fct>          <fct> <fct>   <fct> <fct> <fct> <fct> <fct> <fct> <fct>
 1 8     Albatross    Black-browed   Thal~ melano~ 0     0     0     0     0     0     3.2  
 2 1079  Albatross    Indian Yellow~ Thal~ carteri 0     0     0     0     0     0     3.2  
 3 4150  Albatross    Shy            Thal~ cauta   0     0     0     0     0     0     3.2  
 4 622   Apalis       Bar-throated   Apal~ thorac~ 22    31.8  38.9  33.3  30.8  46.7  38.7 
 5 625   Apalis       Yellow-breast~ Apal~ flavida 9.8   9.1   22.2  11.1  12.8  26.7  16.1 
 6 432   Barbet       Acacia Pied    Tric~ leucom~ 0     0     0     0     2.6   0     0    
 7 431   Barbet       Black-collared Lybi~ torqua~ 63.4  77.3  72.2  50    89.7  73.3  67.7 
 8 439   Barbet       Crested        Trac~ vailla~ 14.6  40.9  38.9  16.7  25.6  13.3  9.7  
 9 433   Barbet       White-eared    Stac~ leucot~ 17.1  18.2  11.1  44.4  35.9  40    35.5 
10 672   Batis        Cape           Batis capens~ 2.4   13.6  11.1  5.6   0     0     0    
# ... with 274 more rows, and 8 more variables: Aug <fct>, Sep <fct>, Oct <fct>, Nov <fct>,
#   Dec <fct>, RepRate <fct>, Records <fct>, Cards <fct>

reprex package (v0.3.0) 于 2020 年 5 月 19 日创建

【讨论】:

  • 这是一个很好的答案,非常感谢。我想再检查一件事。如果您导航到链接link 并向下滚动。您将在“完整协议摘要”下看到您在上面生成的表格,是否可以打印单击“物种列表”选项卡时显示的表格?理想情况下,我希望能够刮掉这张桌子。再次感谢
  • 我尝试将 json 行更改为 json &lt;- strsplit(strsplit(page, "carddataspecies.addRows[(]")[[1]][2], "[)]")[[1]][1],但运行 df 行时出现以下错误 Error: parse error: premature EOF [ [8,"Albatross
猜你喜欢
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-02
  • 1970-01-01
相关资源
最近更新 更多