将列表转换为 JSON 的最佳方法
Best way to convert a list into a JSON
我有一个看起来像这样的脚本(虽然不完全是因为我显然不能提供我的 API 密钥以及不能使它完全可复制的东西)
library(tidyverse)
library(dplyr)
library(httr)
library(civis)
library(rjson)
library(jqr)
record <- GET(
'https://api.secure.com/v4/data',
accept_json(),
add_headers(Accept = 'application/json',
Authorization = VanAPI)
)
record
然后生成一个如下所示的列表:
Response [https://api.secure.com/v4/data]
Date: 2021-08-12 20:54
Status: 200
Content-Type: application/json; charset=utf-8
Size: 873 B
{
"items": [
{
"playerId": 12827,
"name": "Player Tiers",
"type": "Dynamic",
"description": null,
"points": 249,
"areSubgroupsSticky": false,
"status": "Active",
...
将其转换为 JSON 然后我可以将 jqr
包应用到的最佳方法是什么?
现在我在做:
test <- content(record)
产生此输出:
$items
$items[[1]]
$items[[1]]$playerId
[1] 12827
$items[[1]]$name
[1] "Player Tiers"
$items[[1]]$type
[1] "Dynamic"
$items[[1]]$description
NULL
$items[[1]]$points
[1] 249
$items[[1]]$areSubgroupsSticky
[1] FALSE
$items[[1]]$status
[1] "Active"
$items[[1]]$subgroups
NULL
$items[[1]]$markedSubgroup
NULL
$items[[2]]
$items[[2]]$playerId
[1] 15723
$items[[2]]$name
[1] "Team Tiers"
$items[[2]]$type
[1] "Dynamic"
$items[[2]]$description
NULL
$items[[2]]$points
[1] 35
$items[[2]]$areSubgroupsSticky
[1] FALSE
$items[[2]]$status
[1] "Active"
$items[[2]]$subgroups
NULL
$items[[2]]$markedSubgroup
NULL
$items[[3]]
$items[[3]]$playerId
[1] 16620
$items[[3]]$name
[1] "Coaches Tiers"
$items[[3]]$type
[1] "Dynamic"
$items[[3]]$description
NULL
$items[[3]]$points
[1] 12
$items[[3]]$areSubgroupsSticky
[1] FALSE
$items[[3]]$status
[1] "Active"
$items[[3]]$subgroups
NULL
$items[[3]]$markedSubgroup
NULL
$nextPageLink
NULL
$count
[1] 3
但后来我尝试使用 test2 <- rjson::toJSON(test)
将其转换为 JSON 但结果是:
[1] "{\"items\":[{\"playerId\":12827,\"name\":\"Player Tiers\",\"type\":\"Dynamic\",\"description\":null,\"points\":249,\"areSubgroupsSticky\":false,\"status\":\"Active\",\"subgroups\":null,\"markedSubgroup\":null},{\"playerId\":15723,\"name\":\"Team Tiers\",\"type\":\"Dynamic\",\"description\":null,\"points\":35,\"areSubgroupsSticky\":false,\"status\":\"Active\",\"subgroups\":null,\"markedSubgroup\":null},{\"playerId\":16620,\"name\":\"Coaches Tiers\",\"type\":\"Dynamic\",\"description\":null,\"points\":12,\"areSubgroupsSticky\":false,\"status\":\"Active\",\"subgroups\":null,\"markedSubgroup\":null}],\"nextPageLink\":null,\"count\":3}"
有没有更好的方法来获得简单、干净的 JSON 输出?
阅读?content
,你会看到
as: desired type of output: 'raw', 'text' or 'parsed'. 'content'
attempts to automatically figure out which one is most
appropriate, based on the content-type.
继续他们的例子,
library(httr)
r <- POST("http://httpbin.org/post", body = list(a = 1, b = 2))
r
# Response [http://httpbin.org/post]
# Date: 2021-08-12 22:15
# Status: 200
# Content-Type: application/json
# Size: 586 B
# {
# "args": {},
# "data": "",
# "files": {},
# "form": {
# "a": "1",
# "b": "2"
# },
# "headers": {
# "Accept": "application/json, text/xml, application/xml, */*",
# ...
content
的“正常”使用为我们提供了我们期望的命名列表:
str(content(r))
# List of 8
# $ args : Named list()
# $ data : chr ""
# $ files : Named list()
# $ form :List of 2
# ..$ a: chr "1"
# ..$ b: chr "2"
# $ headers:List of 7
# ..$ Accept : chr "application/json, text/xml, application/xml, */*"
# ..$ Accept-Encoding: chr "deflate, gzip"
# ..$ Content-Length : chr "228"
# ..$ Content-Type : chr "multipart/form-data; boundary=------------------------99386898172ff715"
# ..$ Host : chr "httpbin.org"
# ..$ User-Agent : chr "libcurl/7.64.1 r-curl/4.3 httr/1.4.1"
# ..$ X-Amzn-Trace-Id: chr "Root=1-61159d7a-55ef1d2f553f80fa4773ae03"
# $ json : NULL
# $ origin : chr "172.254.236.28"
# $ url : chr "http://httpbin.org/post"
我们可以使用 as="text"
获取原始 json 文本:
content(r, as="text")
# No encoding supplied: defaulting to UTF-8.
# [1] "{\n \"args\": {}, \n \"data\": \"\", \n \"files\": {}, \n \"form\": {\n \"a\": \"1\", \n \"b\": \"2\"\n }, \n \"headers\": {\n \"Accept\": \"application/json, text/xml, application/xml, */*\", \n \"Accept-Encoding\": \"deflate, gzip\", \n \"Content-Length\": \"228\", \n \"Content-Type\": \"multipart/form-data; boundary=------------------------99386898172ff715\", \n \"Host\": \"httpbin.org\", \n \"User-Agent\": \"libcurl/7.64.1 r-curl/4.3 httr/1.4.1\", \n \"X-Amzn-Trace-Id\": \"Root=1-61159d7a-55ef1d2f553f80fa4773ae03\"\n }, \n \"json\": null, \n \"origin\": \"172.254.236.28\", \n \"url\": \"http://httpbin.org/post\"\n}\n"
虽然这并不漂亮,但这正是远程服务器返回的内容:从 http://httpbin.org,/post
端点 returns:
您应该能够使用任何 json 处理器处理此 json,包括 jsonlite::fromJSON
(已确认)并且可能 rjson
和 jqr
(甚至在将其保存到文本文件后在命令行上 jq
。
以下是@r2evans 给出的答案的补充。
尽管 content(r)
似乎是一个 JSON 编码的字符串,jqr 命令将其识别为 JSON 文本,因此(使用 jqr 时)不需要运行 通过 jq 的 fromjson
过滤器。
例如:
> library(httr)
> library(jqr)
> r <- GET("https://raw.githubusercontent.com/postmanlabs/httpbin/master/app.json")
> jq(content(r))
{
"name": "httpbin",
"description": "HTTP Request & Response Service, written in Python + Flask.",
"repository": "https://github.com/requests/httpbin",
"website": "https://httpbin.org",
"logo": "https://s3.amazonaws.com/f.cl.ly/items/333Y191Z2C0G2J3m3Y0b/httpbin.svg",
"keywords": [
"http",
"rest",
"API",
"testing",
"integration",
"python",
"flask"
],
"addons": "sentry"
}
> jq(content(r), ".name")
"httpbin"
我有一个看起来像这样的脚本(虽然不完全是因为我显然不能提供我的 API 密钥以及不能使它完全可复制的东西)
library(tidyverse)
library(dplyr)
library(httr)
library(civis)
library(rjson)
library(jqr)
record <- GET(
'https://api.secure.com/v4/data',
accept_json(),
add_headers(Accept = 'application/json',
Authorization = VanAPI)
)
record
然后生成一个如下所示的列表:
Response [https://api.secure.com/v4/data]
Date: 2021-08-12 20:54
Status: 200
Content-Type: application/json; charset=utf-8
Size: 873 B
{
"items": [
{
"playerId": 12827,
"name": "Player Tiers",
"type": "Dynamic",
"description": null,
"points": 249,
"areSubgroupsSticky": false,
"status": "Active",
...
将其转换为 JSON 然后我可以将 jqr
包应用到的最佳方法是什么?
现在我在做:
test <- content(record)
产生此输出:
$items
$items[[1]]
$items[[1]]$playerId
[1] 12827
$items[[1]]$name
[1] "Player Tiers"
$items[[1]]$type
[1] "Dynamic"
$items[[1]]$description
NULL
$items[[1]]$points
[1] 249
$items[[1]]$areSubgroupsSticky
[1] FALSE
$items[[1]]$status
[1] "Active"
$items[[1]]$subgroups
NULL
$items[[1]]$markedSubgroup
NULL
$items[[2]]
$items[[2]]$playerId
[1] 15723
$items[[2]]$name
[1] "Team Tiers"
$items[[2]]$type
[1] "Dynamic"
$items[[2]]$description
NULL
$items[[2]]$points
[1] 35
$items[[2]]$areSubgroupsSticky
[1] FALSE
$items[[2]]$status
[1] "Active"
$items[[2]]$subgroups
NULL
$items[[2]]$markedSubgroup
NULL
$items[[3]]
$items[[3]]$playerId
[1] 16620
$items[[3]]$name
[1] "Coaches Tiers"
$items[[3]]$type
[1] "Dynamic"
$items[[3]]$description
NULL
$items[[3]]$points
[1] 12
$items[[3]]$areSubgroupsSticky
[1] FALSE
$items[[3]]$status
[1] "Active"
$items[[3]]$subgroups
NULL
$items[[3]]$markedSubgroup
NULL
$nextPageLink
NULL
$count
[1] 3
但后来我尝试使用 test2 <- rjson::toJSON(test)
将其转换为 JSON 但结果是:
[1] "{\"items\":[{\"playerId\":12827,\"name\":\"Player Tiers\",\"type\":\"Dynamic\",\"description\":null,\"points\":249,\"areSubgroupsSticky\":false,\"status\":\"Active\",\"subgroups\":null,\"markedSubgroup\":null},{\"playerId\":15723,\"name\":\"Team Tiers\",\"type\":\"Dynamic\",\"description\":null,\"points\":35,\"areSubgroupsSticky\":false,\"status\":\"Active\",\"subgroups\":null,\"markedSubgroup\":null},{\"playerId\":16620,\"name\":\"Coaches Tiers\",\"type\":\"Dynamic\",\"description\":null,\"points\":12,\"areSubgroupsSticky\":false,\"status\":\"Active\",\"subgroups\":null,\"markedSubgroup\":null}],\"nextPageLink\":null,\"count\":3}"
有没有更好的方法来获得简单、干净的 JSON 输出?
阅读?content
,你会看到
as: desired type of output: 'raw', 'text' or 'parsed'. 'content'
attempts to automatically figure out which one is most
appropriate, based on the content-type.
继续他们的例子,
library(httr)
r <- POST("http://httpbin.org/post", body = list(a = 1, b = 2))
r
# Response [http://httpbin.org/post]
# Date: 2021-08-12 22:15
# Status: 200
# Content-Type: application/json
# Size: 586 B
# {
# "args": {},
# "data": "",
# "files": {},
# "form": {
# "a": "1",
# "b": "2"
# },
# "headers": {
# "Accept": "application/json, text/xml, application/xml, */*",
# ...
content
的“正常”使用为我们提供了我们期望的命名列表:
str(content(r))
# List of 8
# $ args : Named list()
# $ data : chr ""
# $ files : Named list()
# $ form :List of 2
# ..$ a: chr "1"
# ..$ b: chr "2"
# $ headers:List of 7
# ..$ Accept : chr "application/json, text/xml, application/xml, */*"
# ..$ Accept-Encoding: chr "deflate, gzip"
# ..$ Content-Length : chr "228"
# ..$ Content-Type : chr "multipart/form-data; boundary=------------------------99386898172ff715"
# ..$ Host : chr "httpbin.org"
# ..$ User-Agent : chr "libcurl/7.64.1 r-curl/4.3 httr/1.4.1"
# ..$ X-Amzn-Trace-Id: chr "Root=1-61159d7a-55ef1d2f553f80fa4773ae03"
# $ json : NULL
# $ origin : chr "172.254.236.28"
# $ url : chr "http://httpbin.org/post"
我们可以使用 as="text"
获取原始 json 文本:
content(r, as="text")
# No encoding supplied: defaulting to UTF-8.
# [1] "{\n \"args\": {}, \n \"data\": \"\", \n \"files\": {}, \n \"form\": {\n \"a\": \"1\", \n \"b\": \"2\"\n }, \n \"headers\": {\n \"Accept\": \"application/json, text/xml, application/xml, */*\", \n \"Accept-Encoding\": \"deflate, gzip\", \n \"Content-Length\": \"228\", \n \"Content-Type\": \"multipart/form-data; boundary=------------------------99386898172ff715\", \n \"Host\": \"httpbin.org\", \n \"User-Agent\": \"libcurl/7.64.1 r-curl/4.3 httr/1.4.1\", \n \"X-Amzn-Trace-Id\": \"Root=1-61159d7a-55ef1d2f553f80fa4773ae03\"\n }, \n \"json\": null, \n \"origin\": \"172.254.236.28\", \n \"url\": \"http://httpbin.org/post\"\n}\n"
虽然这并不漂亮,但这正是远程服务器返回的内容:从 http://httpbin.org,/post
端点 returns:
您应该能够使用任何 json 处理器处理此 json,包括 jsonlite::fromJSON
(已确认)并且可能 rjson
和 jqr
(甚至在将其保存到文本文件后在命令行上 jq
。
以下是@r2evans 给出的答案的补充。
尽管 content(r)
似乎是一个 JSON 编码的字符串,jqr 命令将其识别为 JSON 文本,因此(使用 jqr 时)不需要运行 通过 jq 的 fromjson
过滤器。
例如:
> library(httr)
> library(jqr)
> r <- GET("https://raw.githubusercontent.com/postmanlabs/httpbin/master/app.json")
> jq(content(r))
{
"name": "httpbin",
"description": "HTTP Request & Response Service, written in Python + Flask.",
"repository": "https://github.com/requests/httpbin",
"website": "https://httpbin.org",
"logo": "https://s3.amazonaws.com/f.cl.ly/items/333Y191Z2C0G2J3m3Y0b/httpbin.svg",
"keywords": [
"http",
"rest",
"API",
"testing",
"integration",
"python",
"flask"
],
"addons": "sentry"
}
> jq(content(r), ".name")
"httpbin"