2017-02-20 57 views
4

我已经设法使用网站API从瑞典统计数据中检索一些数据。 这个问题的答案解决了我的大部分问题。从统计瑞典下载数据。查询中的瑞典语字符

How do I POST a JSON formatted request to GET JSON data from a URL in R into the data.frame in a less verbose manner?

但我仍然有两个问题。

如果我在我的json问题(如“Å”,“Ä”,“Ö”)中带有元音变音字符,我会从服务器收到“404”响应。

我试图从该表中下载数据:

Population 16+ years (RAMS) by region, employment, age and sex. Year 2004 - 2015

(如果单击“继续”你可以查询到在网站上的API,然后“API此表”但你必须响应格式从改变‘PX’到‘JSON’)

此代码:

library(jsonlite) 
library(httr) 

bodytxt <- '{ 
    "query": [ 
{ 
    "code": "Region", 
    "selection": { 
    "filter": "vs:RegionKommun07", 
    "values": [ 
    "0114", 
    "1280" 
    ] 
    } 
}, 
    { 
    "code": "Alder", 
    "selection": { 
    "filter": "item", 
    "values": [ 
    "16-19" 
    ] 
    } 
    }, 
    { 
    "code": "Tid", 
    "selection": { 
    "filter": "item", 
    "values": [ 
    "2015" 
    ] 
    } 
    } 
    ], 
    "response": { 
    "format": "json" 
    } 
    }' 


req <- POST("http://api.scb.se/OV0104/v1/doris/en/ssd/START/AM/AM0207/AM0207H/BefSyssAldKonK", 
      body = bodytxt, encode = "json") 

stop_for_status(req) 
json <- content(req, "text") 


# JSON starts with an invalid character: 
validate(json) 
json <- substring(json, 2) 
validate(json) 

# Now we can parse 
object <- fromJSON(json) 
print(object) 

但如果我更改查询,以便它包含一个“Ö”,它不起作用。例如:

bodytxt <- '{ 
    "query": [ 
    { 
     "code": "Region", 
     "selection": { 
     "filter": "vs:RegionKommun07", 
     "values": [ 
      "0114", 
      "1280" 
      ] 
     } 
    }, 
    { 
     "code": "Sysselsattning", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "FÖRV" 
      ] 
     } 
    }, 
    { 
     "code": "Alder", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "16-19" 
      ] 
     } 
    }, 
    { 
     "code": "Tid", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "2015" 
      ] 
     } 
    } 
    ], 
    "response": { 
    "format": "json" 
    } 
}' 

另一个问题我有是,据我了解,应该可以改变JSON查询到一个列表,其中包括在调用服务器列表中,但我得到一个“404” 误差。例如:

body_list <- fromJSON(bodytxt) 
req <- POST("http://api.scb.se/OV0104/v1/doris/en/ssd/START/AM/AM0207/AM0207H/BefSyssAldKonK", 
      body = body_list, encode = "json") 

我在做什么错?

Ps!我知道它在CRAN上存在一个名为pxweb的优秀软件包,它非常易于从瑞典统计数据下载数据。但我想了解api,并且pxwed不会让我跳过查询中的维度。

系统:Windows 7,R脚本以utf-8编码保存。

回答

3

尝试这些参数fromJSON()

library(httr) 
library(jsonlite) 

数据:

bodytxt <- '{ 
    "query": [ 
    { 
     "code": "Region", 
     "selection": { 
     "filter": "vs:RegionKommun07", 
     "values": [ 
      "0114", 
      "1280" 
      ] 
     } 
    }, 
    { 
     "code": "Sysselsattning", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "FÖRV" 
      ] 
     } 
    }, 
    { 
     "code": "Alder", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "16-19" 
      ] 
     } 
    }, 
    { 
     "code": "Tid", 
     "selection": { 
     "filter": "item", 
     "values": [ 
      "2015" 
      ] 
     } 
    } 
    ], 
    "response": { 
    "format": "json" 
    } 
}' 

修改fromJSON()转换:

query <- jsonlite::fromJSON(bodytxt, 
          simplifyVector=FALSE, 
          simplifyDataFrame=FALSE) 

同一呼叫你做(添加verbose()为我好,但你可以删除):

URL <- "http://api.scb.se/OV0104/v1/doris/en/ssd/START/AM/AM0207/AM0207H/BefSyssAldKonK" 
req <- POST(URL, body=query, encode="json", verbose()) 

结果:

content(req, simplifyDataFrame=TRUE) 

## Warning: JSON string contains (illegal) UTF8 byte-order-mark! 

## $columns 
##    code      text type 
## 1   Region      region d 
## 2 Sysselsattning   employment status d 
## 3   Alder       age d 
## 4   Tid      year t 
## 5  AM0207F2 Population 16+ years (RAMS) c 
## 
## $comments 
## list() 
## 
## $data 
##      key values 
## 1 0114, FÖRV, 16-19, 2015 379 
## 2 1280, FÖRV, 16-19, 2015 1443 

该警告是由于事实API服务器发送一个字节顺序标记回来的结果(这是一个微软服务器,因此它们是一种脑死了,当谈到这一点)。 jsonlite(位于content()内部的位进行转换的位)可以处理它。

+0

完美的作品!谢谢!所以看起来它毕竟不是一个字符编码问题,还是从json到fromJSON()函数中的列表转换以任何方式改变编码? – ChristianL

+0

'fromJSON()'调用不会发生混乱。这只是JSON在发布到API之前转换的方式。它试图对数据分析工作(通常是默认值)“有帮助”,但通常不是其他程序期望使用的。通过这种方式耕耘你将受到表彰。处理定制的API参数调用的额外工作对于许多其他人来说是一个很好的例子,他们毫无疑问将来会如何处理这些问题。 – hrbrmstr

+1

我刚刚意识到,如果我在POST正文的json查询中选择“csv”作为格式,上面的代码将返回格式良好的tibble。也许很高兴知道是否有人想使用代码。 – ChristianL