【问题标题】:Why I get XML Response since my header ask for Json为什么我得到 XML 响应,因为我的标题要求 Json
【发布时间】:2021-04-04 06:17:16
【问题描述】:

我开始使用 Python 和 Alexa RANK API,我有一个小问题,我尝试获取 JSON 响应,但我得到 XML 响应,因为我在我的标题中要求 JSON,如网站 https://awis.alexa.com/developer-guide 中所述

这是我的代码:

import requests
import json

headers = {
    'Accept': 'application/json',
    'x-api-key': 'SMADth1A9xxxxxxxxxxxxxxxxxxxxxxxxxxxEotx',
}

params = (
    ('Action', 'UrlInfo'),
    ('ResponseGroup', 'Rank'),
    ('Url', 'yahoo.com'),
)

response = requests.get('https://awis.api.alexa.com/api', headers=headers, params=params)

结果:

<?xml version="1.0" ?>
<Awis>
  <OperationRequest>
    <RequestId>b14aa999-926d-47c5-87e6-f1fb0f53a40b</RequestId>
  </OperationRequest>
  <Results>
    <Result>
      <Alexa>
        <Request>
          <Arguments>
            <Argument>
              <Name>url</Name>
              <Value>yahoo.com</Value>
            </Argument>
            <Argument>
              <Name>responsegroup</Name>
              <Value>Rank</Value>
            </Argument>
          </Arguments>
        </Request>
        <TrafficData>
          <DataUrl>yahoo.com/</DataUrl>
          <Rank>12</Rank>
        </TrafficData>
      </Alexa>
    </Result>
    <ResponseStatus>
      <StatusCode>200</StatusCode>
    </ResponseStatus>
  </Results>
</Awis>
enter code here

【问题讨论】:

  • 你能分享一下回复的样子吗?你确定它是 XML 吗?如果它实际上没有发回正确的数据格式,这似乎是 Alexa 端某个地方的一个相当明显的错误。如果响应正文是真正的 XML,我会尝试与他们联系。
  • 为什么你的代码和official sample有这么大的不同?
  • @esqew 请仔细检查 ;)
  • @esqew - 没有理由期望特定 API 在不知道它可以/应该这样做的情况下发回任何特定格式。因此,除非他们的文档说 API 支持以 JSON 格式发回结果,否则它不这样做的事实并不是错误。
  • @Steve 我关于这种行为是一个错误的评论的基础植根于 上面链接的文档 OP,它清楚地说明了以下内容,强调我的(以及使用示例cURL 沿 application/jsonAccept 标头值发送):“查询请求只是返回 XML 或 JSON 的 HTTP GET 请求。”正如您所提到的, “他们的文档说 API 支持以 JSON 格式发回结果”。我不确定这里有什么困惑。

标签: python


【解决方案1】:

这是 Alexa 文档中的内容:

Required HTTP Headers:

Accept: application/xml
x-api-key: "YOUR_API_KEY"

必需的标头意味着您必须使用此标头,而 Alexa 仅提供 XML 结果格式。在我看来,Alexa 不提供 json 格式。 Header 只是针对一些低级别的 Web 请求处理程序,而不是应用程序 API 级别。

【讨论】:

  • 我不确定:)
  • 你说得对,为什么只有 XML 回来了。 “Accepts”标头仅在服务器选择接受它并且能够返回指定的响应类型时才有效。如果它能做到,那纯粹是特定 API 的功能和设计的功能。
  • "Header 仅用于一些低级别的 Web 请求处理过程,而不是应用程序 API 级别"。这不是真的。此标头正是 OP 尝试使用它的目的。支持时,它允许服务器以客户端的首选格式发回结果。这发生在服务器应用程序堆栈的哪个位置会有所不同,但有时会在 API 层完成。
  • @AliceMunin - 对不起,我不知道你在问什么或在说什么
  • 这绝对不正确。文档清楚地指出:“查询请求只是一个返回 XML 或 JSON 的 HTTP GET 请求。header 本身是必需的,但与 header 的值无关需要设置为。上述引用出现的同一文档页面包含一个示例 cURL 调用,该调用在 Accept 标头中发送 application/json 值!
【解决方案2】:

由于esqew 指出API 的文档说它会在通过Accepts 标头请求时返回JSON,所以我决定自己尝试OPs 代码。好吧,你猜怎么着......我回来了 JSON。我刚刚在 OPs 代码的末尾添加了print(response.text),我得到了这个:

{
   "Awis":{
      "OperationRequest":{
         "RequestId":"57c6ada1-628d-451b-917f-917c8119406e"
      },
      "Results":{
         "Result":{
            "Alexa":{
               "Request":{
                  "Errors":{
                     "Error":{
                        "ErrorCode":"Forbidden"
                     }
                  }
               }
            }
         },
         "ResponseStatus":{
            "StatusCode":"Forbidden"
         }
      }
   }
}

当然,这是一个错误响应,因为我没有有效的 Api 令牌,但如果 API 能够以 JSON 格式返回错误但查询不成功,我会觉得很奇怪。因此,正如@esqew 指出的那样,这里似乎确实发生了一些可疑的事情。我想不出为什么 OP 会为完全相同的代码获得不同的响应格式。奇怪……

PS:我尝试通过 Accept 标头请求 XML,结果也按预期工作......我得到了 XML。

【讨论】:

    【解决方案3】:

    同意 Alexa awis 仅提供 XML。我可以使用

    headers = {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'x-api-key': key
    }
    

    它仍然返回&lt;?xml version="1.0" ?&gt;

    我最终使用xmltodict 作为:

    import xmltodict
    import json
    my_dict = xmltodict.parse(response.text)
    data = json.dumps(my_dict)
    print(data)
    

    注意data 是一个字符串,只是看起来像 json。如果您需要通过[][]... 传递json 或访问元素,请使用json_data = json.loads(data)。提取alexa排名:

    rank=int(json_data['Awis']['Results']['Result']['Alexa']['TrafficData']['Rank'])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-22
      • 2012-07-11
      • 1970-01-01
      • 2016-11-22
      • 1970-01-01
      • 2019-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多