【问题标题】:Retrieve a single value from json output?从 json 输出中检索单个值?
【发布时间】:2018-10-17 18:18:00
【问题描述】:

我有来自 curl 命令的 json 输出,我想在其中获取一个值,但不知道该怎么做。我正在尝试获取“X-Subject-Token”,如下所示。

阅读我发现我可以使用json.load(sys.stdin)['X-Subject-Token']' 的类似答案。我尝试运行下面的sn-p...

$ curl -v -s -X POST https://host.com:13000/v3/auth/tokens?nocatalog \
       -H "Content-Type: application/json" 
       -d '{\
            "auth": {\
                "identity": {\
                    "methods": [\
                        "password"\
                    ],\
                    "password": {\
                        "user": {\
                            "domain": {\
                                "name": "'"$OS_USER_DOMAIN_NAME"'"\
                            },\
                            "name": "'"$OS_USERNAME"'",\
                            "password": "'"$OS_PASSWORD"'"\
                        }\
                    }\
                },\
                "scope": {\
                    "project": {\
                        "domain": {\
                            "name": "'"$OS_PROJECT_DOMAIN_NAME"'"\
                        },\
                        "name": "'"admin"'"\
                    }\
                }\
            }\
        }' | \
    python -m json.tool | \
    python -c 'import sys, json; print json.load(sys.stdin)['X-Subject-Token']'

...这给了我以下错误:

File "<string>", line 1, in <module>
KeyError: 'X-Subject-Token' 

试图用双引号代替单引号...

print json.load(sys.stdin)["X-Subject-Token"]'

...得到一个不同的错误:

NameError: name 'X' is not defined.

这是我试图从中提取的输出的 sn-p:

> Accept: */*
> Content-Type: application/json
> Content-Length: 245
> 

} [data not shown]
* upload completely sent off: 245 out of 245 bytes
< HTTP/1.1 201 Created
< X-Subject-Token: xxxxxxxxxxxxxxxxxxxxxxx
< Vary: X-Auth-Token
< Content-Type: application/json
< Content-Length: 489

我怎样才能得到X-Subject-Token

我也尝试过 grep 和 awk,我有更多经验,但 Python 似乎是最干净的。

【问题讨论】:

  • 可以显示 JSON 数据吗?
  • 您知道X-Subject-Token 是响应标头而不是任何JSON 的一部分吗?
  • 您显示的数据不是有效的 JSON。 python -n json.tool 的输出是什么?
  • 为什么不用 python requests 库在 Python 中完成这一切?这样,您就可以访问返回的内容以及所有 HTTP 标头等。
  • @jwodder @scnerd 我在这里尝试学习的几个领域。主要是 OpenStack 和 API,所以我偶然发现了 Python 示例并使用了它。我会寻找python requests 的例子,看看我能不能解决它。感谢您的回复。

标签: python json http curl


【解决方案1】:

@jwodder 指出的情况似乎确实如此:X-Subject-Token 不是 JSON 的一部分,而是 HTTP 标头之一。

当您发出 HTTP 请求时,响应带有正文和一系列标头。标头对于服务器和浏览器的正确通信很重要; body 是我们通常想要的信息。由于标头通常(但不总是)仅与服务器和浏览器相关,curl 默认情况下只为我们提供正文。这里我以一些随机的 JSON 为例:

$ curl -X GET https://pastebin.com/raw/S5bxekgg
{"foo": "bar", "a": 2}

身体是如此重要,你甚至相信你需要的信息就在其中——但事实并非如此!它在标题中。在这种情况下,我们还需要curl 来提供标题。很简单,我们只需要给它-i 选项:

$ curl -i -X GET https://pastebin.com/raw/S5bxekgg
HTTP/1.1 200 OK
Date: Mon, 07 May 2018 23:12:36 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=d570bd74e5f34b1ef0d5fe4658ba5e0461525734756; expires=Tue, 07-May-19 23:12:36 GMT; path=/; domain=.pastebin.com; HttpOnly
Cache-Control: public, max-age=1801
Access-Control-Allow-Origin: *
Vary: Accept-Encoding
X-XSS-Protection: 1; mode=block
CF-Cache-Status: HIT
Expires: Mon, 07 May 2018 23:42:37 GMT
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 41775f564ca44bbd-GRU

{"foo": "bar", "a": 2}

现在我们有了更多信息!唉,我的示例不包含您想要的 X-Subject-Token 标头,所以我将使用另一个标头:X-XSS-Protection

但它不在 JSON 中;我们如何得到它?好吧,它更容易:使用 shell!就个人而言,我会用 grep 搜索我想要的标题:

$ curl --silent -i -X GET https://pastebin.com/raw/S5bxekgg | grep X-XSS-Protection
X-XSS-Protection: 1; mode=block

一旦我拥有它,我会使用cut 取出值:

$ curl --silent -i -X GET https://pastebin.com/raw/S5bxekgg | grep X-XSS-Protection | cut -d: -f2
1; mode=block

而且它只是其中一种选择!我们甚至不需要 Python!

所以,如果我的假设是正确的,那么问题不在于 Python,而是您将 HTTP 响应标头与 HTTP 响应主体混淆了。如果你要处理很多概念,可能会有点乱,但没有什么是实践解决不了的;)

【讨论】:

    【解决方案2】:

    X-Subject-Token 是响应中的 http 标头。您可以使用 curl 的 --include 标志将响应标头打印到标准输出。然后,您只需使用例如 awk 提取它。

    curl --include -v -s -X POST https://host.com:13000/v3/auth/tokens?nocatalog |\
    [ more options ] |\
    awk '/X-Subject-Token/ { print $2 }'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-24
      • 1970-01-01
      • 1970-01-01
      • 2018-04-27
      • 2018-11-20
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      相关资源
      最近更新 更多