【问题标题】:Scraping php-generated html tables in R在 R 中抓取 php 生成的 html 表
【发布时间】:2020-08-22 15:05:02
【问题描述】:

我想从这个网站上抓取数据http://demo.istat.it/bilmens2012gen/index02.html 在左边有一个网络表单,它将参数传递给一个 php 页面,该页面又输出生成的 html 表并在同一页面的一个框架中。 从第一个下拉列表中有 107 个城市,从第二个 12 个月开始,我应该手动运行 1.284 个查询来收集所需的数据。 对自动化这个过程有什么建议吗? 我使用 R 和 rvest 库来抓取静态 html 表,但由于这些表是由表单参数生成的,所以我不知道该怎么做。希望我可以组合参数(如“city1”“month1”)并检索 html,然后做我的工作来加入数据。

【问题讨论】:

    标签: php html r web-scraping


    【解决方案1】:

    这是一个相当简单的抓取工作。当您选择页面上的按钮时,浏览器只是从服务器请求一些 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
    

    所以你可以这样做来获取所有的 url:

    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)
    

    显然我没有对此进行测试,因为下载和处理所有表格可能需要大约一个小时。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 2020-09-28
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多