php - 在 R 中抓取 php 生成的 html 表
问题描述
我想从这个网站上抓取数据http://demo.istat.it/bilmens2012gen/index02.html 在左边有一个网络表单,它将参数传递给一个 php 页面,该页面又输出生成的 html 表并在一个框架中同一页。从第一个下拉列表中有 107 个城市,从第二个 12 个月开始,我应该手动运行 1.284 个查询来收集所需的数据。对自动化这个过程有什么建议吗?我使用 R 和 rvest 库来抓取静态 html 表,但由于这些表是由表单参数生成的,所以我不知道该怎么做。希望我可以组合参数(如“city1”“month1”)并检索 html,然后再做我的工作来加入数据。
解决方案
这是一个相当简单的抓取工作。当您选择页面上的按钮时,浏览器只是从服务器请求一些 html 并将其放入主框架中。请求只是以这种格式编码在 url 中:
Province (1 - 107) Period (1 - 12)
| |
v v
http://demo.istat.it/bilmens2012gen/query1.php?lingua=ita&Pro=1&allrp=4&periodo=1&submit=Tavola
所以你可以这样做来获取所有的网址:
urls <- do.call("c",
lapply(1:107,
function(x) paste0("http://demo.istat.it/bilmens2012gen/",
"query1.php?lingua=ita&Pro=", x,
"&allrp=4&periodo=", 1:12,
"&submit=Tavola")
)
)
当然,您仍然需要从这些页面中抓取数据。下面是一个从每个链接获取数据的函数示例:
get_table <- function(url)
{
df <- xml2::read_html(url) %>%
html_nodes("table") %>%
`[`(2) %>% html_table()
df <- df[[1]]
breaks <- which(df[,1] == "CodiceComune")
output <- df[(breaks[1] + 2):(breaks[2] - 1),]
output <- setNames(output, paste(df[1,], df[2,]))
for(i in 3:8) output[[i]] <- as.numeric(as.character(output[[i]]))
dplyr::as_tibble(output)
}
所以我可以像这样得到第一个区域的第一个时期:
get_table(urls[1])
#> # A tibble: 315 x 11
#> `CodiceComune T~ `Comuni Totale` `Popolazioneini~ `Nati Vivi Tota~ `Morti Totale`
#> <chr> <chr> <dbl> <dbl> <dbl>
#> 1 001269 Strambino 6314 1 5
#> 2 001270 Susa 6626 2 10
#> 3 001271 Tavagnasco 812 0 1
#> 4 001272 Torino 869312 749 1011
#> 5 001273 Torrazza Piemo~ 2833 2 4
#> 6 001274 Torre Canavese 592 1 1
#> 7 001275 Torre Pellice 4514 4 8
#> 8 001276 Trana 3877 2 5
#> 9 001277 Trausella 132 0 1
#> 10 001278 Traversella 351 0 0
#> # ... with 305 more rows, and 6 more variables: `SaldoNaturale Totale` <dbl>, `Iscritti
#> # Totale` <dbl>, `Cancellati Totale` <dbl>, `Saldomigratorio e per altri motivi Totale` <chr>,
#> # `Unità inpiù/menodovute avariazioniterritoriali Totale` <chr>, `Popolazionefine periodo
#> # Totale` <chr>
当然,您可能希望设置一个循环来获取所有页面并将数据框粘合在一起,可能像这样:
result_list <- list()
for(i in seq_along(urls))
{
cat("Getting url", i, "of", length(urls), "\n")
result_list[[i]] <- get_table(urls[i])
}
result_df <- do.call(rbind, result_list)
显然我没有对此进行测试,因为下载和处理所有表格可能需要大约一个小时。
推荐阅读
- json - 如何在颤动中将图像作为base64字符串发布到api服务器
- javascript - 提取以 a 和 b 开头的口袋妖怪
- javascript - Sails js客户端原生websocket
- java - 我的读者和作者在这种方法中没有正确关闭吗?
- asp.net-core - 更改 VS2019 输出的颜色
- javascript - 如何等到函数结束才能继续代码节点js
- python - 使用无头 Firefox 时 Selenium 错误的屏幕截图分辨率
- javascript - 具有一个全屏功能的多个图像?
- powershell - 获取安装在远程服务器上的特定 KB
- python - 一旦选择并按下 QButton,如何从 QListWidget 对象中获取项目作为字符串