メモ:国土数値情報のウェブページから各データの説明のURLをrvestとstringrで抜き出す
国土数値情報APIはzipファイルのURLを返してくれるんですけど、それがどういうデータかは教えてくれません。
library(dplyr, warn.conflicts = FALSE) library(kokudosuuchi) #> このサービスは、「国土交通省 国土数値情報(カテゴリ名)」をもとに加工者が作成 #> 以下の国土数値情報ダウンロードサービスの利用約款をご確認の上ご利用ください: #> #> http://nlftp.mlit.go.jp/ksj/other/yakkan.html # prefCodeが3で、年が2000-2010の河川のデータ d <- getKSJURL("W05", prefCode = 3, fiscalyear = 2000:2010) glimpse(d) #> Observations: 1 #> Variables: 9 #> $ identifier <chr> "W05" #> $ title <chr> "河川" #> $ field <chr> "国土(水・土地)" #> $ year <chr> "2007" #> $ areaType <chr> "3" #> $ areaCode <chr> "3" #> $ datum <chr> "1" #> $ zipFileUrl <chr> "http://nlftp.mlit.go.jp/ksj/gml/data/W05/W05-07/W... #> $ zipFileSize <chr> "10.42MB"
どういうデータか書いてあるページには、国土数値情報のウェブページから飛べます。
とりあえずリンクを全部抜き出してみるとこんな感じ。
library(rvest) library(dplyr, warn.conflicts = FALSE) page <- read_html("http://nlftp.mlit.go.jp/ksj/index.html") a_nodes <- page %>% html_nodes(css = "td > a") d <- tibble::tibble(url = html_attr(a_nodes, "href"), name = html_text(a_nodes)) d #> # A tibble: 113 x 2 #> url name #> <chr> <chr> #> 1 http://nlftp.mlit.go.jp/ksj-e/index.html ENGLISH #> 2 api/about_api.html Web API #> 3 index.html GML(JPGIS2.1)シェープファイル #> 4 jpgis/jpgis_datalist.html XML(JPGIS1.0) #> 5 gmlold/index.html GML(JPGIS2.1)シェープファイル #> 6 old/old_datalist.html テキスト #> 7 gml/datalist/KsjTmplt-C23.html 海岸線 #> 8 gml/datalist/KsjTmplt-P23.html 海岸保全施設 #> 9 gml/datalist/KsjTmplt-W09-v2_2.html 湖沼 #> 10 gml/datalist/KsjTmplt-W07.html 流域メッシュ #> # ... with 103 more rows
この、gml/datalist/KsjTmplt-C23.html
とかgml/datalist/KsjTmplt-P23.html
とかが、それぞれC23
、P23
のデータの説明ページになっています。これは、
gml/datalist/KsjTmplt-識別子.html
というフォーマットになっていると思いきや、gml/datalist/KsjTmplt-W09-v2_2.html
のようにトリッキーなものもあって一筋縄ではいきません。
library(stringr) str_extract(d$url, "KsjTmplt-.*\\.html") %>% purrr::discard(is.na) %>% head(20) #> [1] "KsjTmplt-C23.html" "KsjTmplt-P23.html" "KsjTmplt-W09-v2_2.html" #> [4] "KsjTmplt-W07.html" "KsjTmplt-W01.html" "KsjTmplt-W05.html" #> [7] "KsjTmplt-G04-a.html" "KsjTmplt-G04-c.html" "KsjTmplt-G04-d.html" #> [10] "KsjTmplt-G08-v1_0.html" "KsjTmplt-L03-a.html" "KsjTmplt-L03-b.html" #> [13] "KsjTmplt-L03-b-u.html" "KsjTmplt-A13.html" "KsjTmplt-A12.html" #> [16] "KsjTmplt-A09.html" "KsjTmplt-A29.html" "KsjTmplt-L01-v2_3.html" #> [19] "KsjTmplt-L02-v2_3.html" "KsjTmplt-N03-v2_3.html"
とりあえずコードっぽい部分だけを抜き出しましょう。これにはlook aheads/behindsを使います(参考:正規表現の先読み・後読みを極める! - あらびき日記)
str_extract(d$url, "(?<=KsjTmplt-).*(?=\\.html)") %>% purrr::discard(is.na) %>% head(20) #> [1] "C23" "P23" "W09-v2_2" "W07" "W01" "W05" #> [7] "G04-a" "G04-c" "G04-d" "G08-v1_0" "L03-a" "L03-b" #> [13] "L03-b-u" "A13" "A12" "A09" "A29" "L01-v2_3" #> [19] "L02-v2_3" "N03-v2_3"
よさそうです。次に、-v2_3
みたいな部分を取りましょう。これは後ろに(-v\\d_\\d+)?
を入れるだけでOK、だと思ったんですが…
str_extract(d$url, "(?<=KsjTmplt-).*(?=(-v\\d_\\d+)?\\.html)") %>% purrr::discard(is.na) %>% head(20) #> [1] "C23" "P23" "W09-v2_2" "W07" "W01" "W05" #> [7] "G04-a" "G04-c" "G04-d" "G08-v1_0" "L03-a" "L03-b" #> [13] "L03-b-u" "A13" "A12" "A09" "A29" "L01-v2_3" #> [19] "L02-v2_3" "N03-v2_3"
変わりません。これは、.*
がgreedy matchなので-v2_3
までマッチしてしまうからです。ということで正解は、.*?
にすることです(そもそも.*
じゃなくてもうちょっと絞り込んだ表現にするというのもあり)。
str_extract(d$url, "(?<=KsjTmplt-).*?(?=(-v\\d_\\d+)?\\.html)") %>% purrr::discard(is.na) %>% head(20) #> [1] "C23" "P23" "W09" "W07" "W01" "W05" "G04-a" #> [8] "G04-c" "G04-d" "G08" "L03-a" "L03-b" "L03-b-u" "A13" #> [15] "A12" "A09" "A29" "L01" "L02" "N03"
こんな感じ。
KSJCodeDescriptionURL <- d %>% mutate(code = str_extract(url, "(?<=KsjTmplt-).*?(?=(-v\\d+_\\d+)?\\.html)"), url = glue::glue('http://nlftp.mlit.go.jp/ksj/{url}')) %>% filter(!is.na(code)) %>% arrange(code) glimpse(KSJCodeDescriptionURL) #> Observations: 105 #> Variables: 3 #> $ url <S3: glue> "http://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-A03.ht... #> $ name <chr> "三大都市圏計画区域", "都市地域", "自然公園地域", "自然保全地域", "農業地域", "森林地域", "鳥獣保護... #> $ code <chr> "A03", "A09", "A10", "A11", "A12", "A13", "A15", "A16", "A17",...