2016-11-23 3 views
3

Я хочу очистить этот website и получить данные из таблицы.httr Функция чтения таблицы GET

Я использую GET из пакета httr, код, как показано ниже:

url <- 'http://datacenter.mep.gov.cn/report/water/water.jsp?' 
year <- 2016 
wissue <- 2 

res <- GET(url, 
      query = list(year = year, 
         wissue = wissue)) 


resC <- content(res, as = 'text', encoding = 'utf-8') 

Но то, что я получил, это не строка JSON, но что-то очень странно, как показано ниже:

"\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<html>\r\n\t<head>\r\n\t\t<title>中华人民共和国环境保护部--政府网站数据中心</title>\r\n\t\t<meta http-equiv=\"content-type\" content=\"text/html; 

Интересно, является все равно, чтобы разобрать этот формат?

ответ

1

Атрибут rowspan позволит сделать сделку с этой таблицей довольно интересной. У вас есть несколько вариантов, два из которых являются:

  1. использование html_table() на цели <table> использование fill=TRUE и выполнить операцию на результирующем кадре данных
  2. атаковать его на <tr> -й и строить кадр данных из земля

Этот ответ делает последний.

library(rvest) 
library(purrr) 

Во-первых, мы получаем содержимое в виде мы можем выполнить XML/HTML операцию на:

content(res, as = 'text', encoding = 'utf-8') %>% 
    read_html() -> pg 

Далее мы ориентируемся и извлечь узел таблицы с отчетом:

tab <- html_nodes(pg, "table#report1") 

Вот трюк бит. Мы первая цель всех <tr> элементов, которые имеют @rowspan атрибуты, но не <td> элементов с @colspan атрибутом:

html_nodes(tab, xpath=".//tr[td[not(@colspan) and @rowspan]]") %>% 

Далее, мы не обработаем те invidivually:

map_df(function(x) { 

Мы получаем # строк в <tr> пролетах :

html_nodes(x, xpath=".//td[@rowspan]") %>% 
     html_attr("rowspan") %>% 
     as.numeric() -> row_ct 

Найти все одноуровневые <tr> элементы и уменьшить установить на оставшихся в этом <tr> «блока»:

rows <- html_nodes(x, xpath=".//following-sibling::tr") 
    rows <- rows[1:(row_ct-1)] 

сделать кадр данных от первого блока строки

html_nodes(x, xpath=".//td") %>% 
     html_text() %>% 
     setNames(sprintf("X%d", 1:13)) %>% 
     as.list() %>% 
     flatten_df() -> first 

пройти через все отфильтрованные строки двойников и сделать то же самое, оставляя место для заполнения в составном колонке:

map_df(rows, ~html_nodes(., xpath=".//td") %>% 
      html_text() %>% 
      setNames(c("X1", "X2", sprintf("X%d", 4:13))) %>% 
      as.list()) %>% 
     mutate(X3=first$X3) %>% 
     select(X1, X2, X3, everything()) -> rest 

    bind_rows(first, rest) 

    }) -> h2o_df 

dplyr::glimpse(h2o_df) 

Я не могу вставить вывод, что поскольку SO это Javascript текстовый фильтр так мозг мертв он считает, что сообщение является спамом только б/с ней час как персонажи кандзи.

Вот весь код в непрерывный кусок:

tab <- html_nodes(pg, "table#report1") 

html_nodes(tab, xpath=".//tr[td[not(@colspan) and @rowspan]]") %>% 
    map_df(function(x) { 

    html_nodes(x, xpath=".//td[@rowspan]") %>% 
     html_attr("rowspan") %>% 
     as.numeric() -> row_ct 

    rows <- html_nodes(x, xpath=".//following-sibling::tr") 
    rows <- rows[1:(row_ct-1)] 

    html_nodes(x, xpath=".//td") %>% 
     html_text() %>% 
     setNames(sprintf("X%d", 1:13)) %>% 
     as.list() %>% 
     flatten_df() -> first 

    map_df(rows, ~html_nodes(., xpath=".//td") %>% 
      html_text() %>% 
      setNames(c("X1", "X2", sprintf("X%d", 4:13))) %>% 
      as.list()) %>% 
     mutate(X3=first$X3) %>% 
     select(X1, X2, X3, everything()) -> rest 

    bind_rows(first, rest) 

    }) -> h2o_df 
+0

Спасибо за подробный ответ! Раньше я использовал 'html_table()', но обычно функция автоматически определяет таблицу, но почему в этот раз таблица, которую я получил через 'html_table()', настолько запутанна, и когда я пытаюсь записать ее в файл, она говорит о различном числе из строк .... не могли бы вы рассказать мне, как это решить? – ycx

+0

нет простого выхода из этого соскабливания. сайт использует 'colspan' и' rowspan' во многих '' элементах, чтобы сделать таблицу «красивой» для пользователя (это отвратительно, если вы спросите меня), что очень сильно скрежет. 'html_table()' может сделать много образованных догадок, но он будет заполнять фрейм данных довольно плохо, когда есть 'rowspan' s участие (это довольно прилично с 'colspan's). – hrbrmstr

+0

ОК, вижу, спасибо! Я просто попробую 2-й путь! – ycx

Смежные вопросы