R 网页抓取检测单个国家/地区的最高数值 GADM.org 级别



如果浏览到 gadm.org/country,选择一个国家/地区和 R 空间多边形作为数据类型,则可以下载该特定国家/地区的可用 gadm.org 管理级别集。可用的级别因国家/地区而异。

有没有办法通过函数获取国家/地区可用的级别(或只是最低地理级别,最高数字级别),而无需实际下载文件?

理想情况下,我会有这样工作的代码(组成函数,而不是工作):

getGADMmaxlevel("Nigeria")
[1] 2
getGADMmaxlevel("Haiti")
[1] 4
getGADMmaxlevel("Philippines")
[1] 3

我为什么要这样做: 我希望能够在我创建的单独函数中下载和删除 gadm 文件,允许跨具有大量不同国家的数据集进行循环,而不会占用磁盘空间(即数据集最多可以获得 100 个或更多国家)。这个想法是让所有国家都有相同的gadm提取水平,一个最高的数字通用水平。因此,在下载任何单个国家/地区的文件之前,我需要该集合中所有国家/地区可供下载的级别列表,以确定集合中最高的数字通用级别(即数据集中整组国家/地区共有的最高数字 gadm 层)。然后我可以下载并删除 gadm 文件,而不是一次保留所有文件以确定它们之间的最高公共级别。

想法

数据集延迟加载:我可以下载整个世界,并使用grepl对ID_列中的 na 值进行检查,以仅获取从 ID_ 开始的列,which(is.na())获取最后可用ID_而不是所有 NA 按国家/地区划分的列。然后,我需要我正在构建的包中的数据集(小而乏味)并在我的函数中调用它。这是我迄今为止想到的最好的方法,但听起来很乏味。

网页抓取:gadm.org UI 明确使用 cookie 滚动到下载页面(下载链接页面不是静态链接)。但是,实际的下载链接是静态的:即海地4级是 http://biogeo.ucdavis.edu/data/gadm2.8/rds/HTI_adm4.rds 从理论上讲,我可以检查链接是否有效并增加 adm#,直到它不起作用,获取最后一个有效的链接并使用 substr 提取级别。这听起来也不好玩,而且听起来也很慢。

网页抓取 2:httr 和 rvest 通过并保存 cookie 以进入下载链接页面,保存下载链接。这将非常复杂,因为可能有针对 R 数据类型和国家/地区等的 post 请求(呃!),并且在 html 链接之前通过三个页面的速度很慢。

有什么更好的主意吗?

>如果 POST 表单相对简单,rvest 可以处理它们,就像这个一样,因此您只需抓取表单的每个值和下一页上可能的级别选择即可构建国家/地区和级别的数据框。

首先,在表单页面上打开 rvest 会话并解析要迭代的选择值(国家/地区):

library(tidyverse)
library(rvest)
gadm_search <- html_session('http://gadm.org/country')
countries <- gadm_search %>% 
html_nodes('select[name="cnt"] option') %>% 
html_attr('value')

准备并存储表单(预设数据格式选择,但如果您愿意,可以在迭代时执行此操作):

gadm_form <- gadm_search %>% html_form() %>% .[[1]] %>% set_values(thm = "rds#R data")

。然后迭代:

gadm_levels <- countries %>% 
head() %>%    # plenty for now
map_df(~{
Sys.sleep(10);    # per http://gadm.org/robots.txt
data_frame(country = .x,
url = gadm_form %>% 
set_values(cnt = .x) %>% 
submit_form(gadm_search, .) %>% 
html_nodes('b a') %>% 
html_attr('href'))
})

由于这会为您提供URL,因此要获得最高级别,您需要进行一些解析和总结,例如

gadm_levels %>% 
mutate(admin_level = parse_number(basename(url))) %>% 
group_by(country) %>% 
top_n(1, admin_level) %>% 
select(-url)
#> # A tibble: 6 x 2
#> # Groups:   country [6]
#>   country                     admin_level
#>   <chr>                             <dbl>
#> 1 AFG_Afghanistan_3                    2.
#> 2 XAD_Akrotiri and Dhekelia_2          1.
#> 3 ALA_Åland_2                          1.
#> 4 ALB_Albania_4                        3.
#> 5 DZA_Algeria_3                        2.
#> 6 ASM_American Samoa_4                 3.

这样做表明选择末尾的那些数字似乎是最大级别 + 1,这意味着您可以只抓取它们而根本不迭代:

gadm_levels2 <- 'http://gadm.org/country' %>% 
read_html() %>% 
html_nodes('select[name="cnt"] option') %>% 
html_attr('value') %>% 
data_frame(countries = .) %>% 
separate(countries, c('iso3c', 'country', 'level'), sep = '_', convert = TRUE) %>% 
mutate(level = level - 1L)
gadm_levels2
#> # A tibble: 254 x 3
#>    iso3c country               level
#>    <chr> <chr>                 <int>
#>  1 AFG   Afghanistan               2
#>  2 XAD   Akrotiri and Dhekelia     1
#>  3 ALA   Åland                     1
#>  4 ALB   Albania                   3
#>  5 DZA   Algeria                   2
#>  6 ASM   American Samoa            3
#>  7 AND   Andorra                   1
#>  8 AGO   Angola                    3
#>  9 AIA   Anguilla                  0
#> 10 ATA   Antarctica                0
#> # ... with 244 more rows

不过,您应该验证该数据是否是看起来的那样。

最新更新