首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >httr函数读取表

httr函数读取表
EN

Stack Overflow用户
提问于 2016-11-23 08:06:20
回答 1查看 1.3K关注 0票数 3

我想刮掉这个网站,并从表中获取数据。

我从包GET使用httr,代码如下所示:

代码语言:javascript
复制
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')

但我得到的不是一根麻绳,而是一种很奇怪的东西,如下所示:

代码语言:javascript
复制
"\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;

我想知道是否有解析这种格式的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-23 12:13:58

rowspan属性将使处理这个表变得非常有趣。你有几个选择,其中两个是:

  1. 使用html_table()在目标<table>上使用fill=TRUE,并对结果数据帧执行手术
  2. 攻击<tr>-level并从头开始构建数据框架

这个答案就是后者。

代码语言:javascript
复制
library(rvest)
library(purrr)

首先,我们以可以在以下方面执行XML/HTML操作的形式获取内容:

代码语言:javascript
复制
content(res, as = 'text', encoding = 'utf-8') %>% 
  read_html() -> pg

接下来,我们使用报告针对并提取表节点:

代码语言:javascript
复制
tab <- html_nodes(pg, "table#report1") 

这是个棘手的问题。我们首先针对所有具有<tr>属性但没有具有@colspan属性的<td>元素的<td>元素:

代码语言:javascript
复制
html_nodes(tab, xpath=".//tr[td[not(@colspan) and @rowspan]]") %>% 

接下来,我们对这些自然现象进行处理:

代码语言:javascript
复制
  map_df(function(x) {

我们得到了<tr>跨越的行的#:

代码语言:javascript
复制
    html_nodes(x, xpath=".//td[@rowspan]") %>% 
      html_attr("rowspan") %>% 
      as.numeric() -> row_ct

查找所有同级<tr>元素,并将该集合缩减为此<tr>“块”中的其余元素:

代码语言:javascript
复制
    rows <- html_nodes(x, xpath=".//following-sibling::tr")
    rows <- rows[1:(row_ct-1)] 

从第一个块行创建一个数据帧。

代码语言:javascript
复制
    html_nodes(x, xpath=".//td") %>% 
      html_text() %>% 
      setNames(sprintf("X%d", 1:13)) %>% 
      as.list() %>% 
      flatten_df() -> first

遍历所有经过过滤的兄弟行,并做同样的操作,留出空间填充跨列:

代码语言:javascript
复制
    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文本过滤器太死气沉沉了,以至于它认为post是垃圾邮件,只是b/c,它有kanji字符。

下面是一个连续块中的所有代码:

代码语言: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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40759002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档