首页 > 解决方案 > 不同的 URL 格式使用 Python 的 requests.get 从相同的 API 返回不同的数据类型

问题描述

当这两种 URL 格式都从同一个 API 中提取数据时,为什么它们会返回不同的数据类型?

这将返回一个嵌套字典,它是正确的类型:

user = requests.get('https://jsonplaceholder.typicode.com/users/{}'.format(1)).json()

输出:

{
  'id': 1,
  'name': 'Leanne Graham',
  'username': 'Bret',
  'email': 'Sincere@april.biz',
  'address': {
    'street': 'Kulas Light',
    'suite': 'Apt. 556',
    'city': 'Gwenborough',
    'zipcode': '92998-3874',
    'geo': {
      'lat': '-37.3159',
      'lng': '81.1496'
    }
  },
  'phone': '1-770-736-8031 x56442',
  'website': 'hildegard.org',
  'company': {
    'name': 'Romaguera-Crona',
    'catchPhrase': 'Multi-layered client-server neural-net',
    'bs': 'harness real-time e-markets'
  }
}

虽然这会返回一个字典列表:

user = requests.get('https://jsonplaceholder.typicode.com/users?id={}'.format(1)).json()

输出:

[{
  'id': 1,
  'name': 'Leanne Graham',
  'username': 'Bret',
  'email': 'Sincere@april.biz',
  'address': {
    'street': 'Kulas Light',
    'suite': 'Apt. 556',
    'city': 'Gwenborough',
    'zipcode': '92998-3874',
    'geo': {
      'lat': '-37.3159',
      'lng': '81.1496'
    }
  },
  'phone': '1-770-736-8031 x56442',
  'website': 'hildegard.org',
  'company': {
    'name': 'Romaguera-Crona',
    'catchPhrase': 'Multi-layered client-server neural-net',
    'bs': 'harness real-time e-markets'
  }
}]

请注意不同的网址格式

这是代码示例:

#!/usr/bin/python3
import sys
import requests
if __name__ == "__main__":
    user = requests.get('https://jsonplaceholder.typicode.com/users?id={}'.format(1)).json()
    print(user)

标签: pythonpython-requests

解决方案


这与 Python 无关,requests.get也与 URL 格式无关。它是决定如何解析该 URL 以及如何映射其元素的服务。

  • 在第一种情况下https://jsonplaceholder.typicode.com/users/1被视为单个资源标识符(它是),因此服务返回一个序列化为 JSON 的单个对象。在 JavaScript 中,对象字典。您发布的是单个对象,而不是嵌套字典

  • 在第二种情况下,https://jsonplaceholder.typicode.com/users?id=1它将 URL 视为对Users具有过滤器的资源的查询,id=1因此即使只有一个匹配的对象,它也会返回一个对象数组。

JSONPlaceholder 的文档解释说此语法用于过滤:

过滤资源

通过查询参数支持基本过滤。

另一个服务可以决定,因为id它是一个键,它应该返回一个对象而不是一个数组。或者它可以使用不同的查询字符串,例如使用filter显式指定过滤器参数

两种情况都没有标准。虽然在 URL 路径中包含对象 ID 是一种常见的约定,尤其是在类似 REST 的 API 中,但对于查询没有单一的标准甚至约定。每个服务都使用自己的格式。

GraphQL(来自 Facebook)和 OData(来自 Microsoft)是两种常见的查询和操作协议。虽然它们比 JSONPlaceholder 使用的非常简单的过滤要复杂得多


推荐阅读