2016-11-23 31 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並在<tr> -level得到的數據幀進行手術
  2. 攻擊它,並建立從數據幀上爬起來

這個答案確實是後者。

library(rvest) 
library(purrr) 

首先,我們就得到了一個形式的內容,我們可以執行XML/HTML術:

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

接下來,我們的目標,並提取與報告表節點:

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

這是棘手的一點。我們首先針對所有具有@rowspan屬性<tr>元素,但沒有<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文本過濾器是如此腦死它認爲該職位是垃圾郵件只是b/C它^ h作爲漢字字符。

下面是一個連續的大塊所有代碼:

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'時,它會非常糟糕地填充數據框(這對'colspan'來說是相當不錯的)。 – hrbrmstr

+0

好的,我明白了,非常感謝!我會嘗試第二種方式! – ycx