Очистка php -генерированных html таблиц в R - PullRequest
0 голосов
/ 07 мая 2020

Я хочу очистить данные с этого веб-сайта http://demo.istat.it/bilmens2012gen/index02.html Слева есть веб-форма, которая передает параметры на страницу php, которая, в свою очередь, выводит результирующие таблицы html и во фрейме на той же странице. В первом раскрывающемся списке есть 107 городов, а со второго 12 месяцев, поэтому я должен вручную запустить 1,284 запроса для сбора желаемых данных. Есть предложения по автоматизации этого процесса? Я использовал библиотеку R и rvest для очистки таблиц stati c html, но поскольку эти таблицы генерируются параметрами формы, я не знаю, как это сделать. Wi sh Я мог бы комбинацию параметров (например, «city1» «month1») и получить html, а затем выполнить свои действия для объединения данных.

1 Ответ

1 голос
/ 07 мая 2020

Это довольно простая работа по очистке. Когда вы выбираете кнопки на странице, браузер просто запрашивает у сервера некоторое количество 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>

Конечно, вам нужно настроить al oop, чтобы собрать все страницы и склеить фреймы данных, возможно, вот так:

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)

Очевидно, я не тестировал это, так как это может занять около часа для загрузки и обработки всех таблиц.

...