【问题标题】:Send Json (contains boolean/numbers) data in python GET(Method) requests在 python GET(方法)请求中发送 Json(包含布尔值/数字)数据
【发布时间】:2018-02-28 10:37:01
【问题描述】:

问。是否可以通过 GET 请求发送 json 数据?

我想传递一些过滤器参数来从数据库中读取结果

params = {'is_coming_soon': False, 'is_paid': True, 'limit': 100, 'skip': 0}
headers = {'content-type': 'application/json'}
response = requests.get(url=url, headers=headers, params=params)

在服务器端,我接收所有值作为 string,

我怎样才能请求获得正确的布尔值而不是字符串一。

【问题讨论】:

  • json 没有布尔值 iirc
  • @SitiSchu 呃,你从哪里得到的? a = json.dumps({'a': True}) --> '{"a": true}'
  • @roganjosh ähem,nvm 忘了我说的 ^^
  • @MonishKNair -- 我不认为这是 8634473 的副本。

标签: python json python-requests


【解决方案1】:

要发送 json 有效负载,请使用 datajson 参数而不是 params。首先使用json.dumps 将dict转换为json,如果你愿意,请仔细检查转换:

import json

payload = json.dumps(params)
print(payload)  # '{"is_coming_soon": false, "is_paid": true, "limit": 100, "skip": 0}'

response = requests.get(url=url, headers=headers, data=payload)

另外,您可以像这样调试requests 调用:

import requests
import logging

from http.client import HTTPConnection
# from httplib import HTTPConnection  # Python 2

HTTPConnection.debuglevel = 1

logging.basicConfig() 
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

response = requests.get(url=url, headers=headers, data=payload)

【讨论】:

  • 谢谢@brennan,这行得通,现在我只需要更新服务器端请求解析机制。
  • 更正:请求(getpost 调用)同时处理关键字参数数据和 json。只有在使用 json= 时,Python 对象才会被 JSON 序列化。如果您使用data=,您需要自己处理。
【解决方案2】:

总结:

没有使用 params 参数的内置选项,并且将 bool 值从 python True|False 转换为 json true|false

我们必须手动处理布尔值以将它们转换为小写字符串。下面介绍几种处理方法。

例如: 对各个值进行编码 'true' if x else 'false'json.dumps(x)

为什么

requests.request 的内部方法使用字符串化来转换任何非字符串值。请参阅PreparedRequest 中的prepare_url

如果同时使用查询和参数,则 enc_params 由'%s&%s' % (query, enc_params) 转换为字符串。如果不是,那么query=enc_params 是在requote_url 内编码的字符串。

### excerpt from PreparedRequest.prepare_url

        enc_params = self._encode_params(params)
        if enc_params:
            if query:
                query = '%s&%s' % (query, enc_params)
            else:
                query = enc_params

        url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment]))
        self.url = url
str(True)         # 'True'
str(False)        # 'False'
'%s' % True       # 'True

import json
json_dumps(None)  # 'null'   <-- probably want to avoid null for Boolean values
json.dumps(True)  # 'true'   <-- lowercase
json.dumps(False) # 'false'  <-- lowercase

如何

对于一两个值,您可以使用简单的三元,但这很快就会变得冗长。

is_coming_soon, is_paid = False, True
params = {'is_coming_soon': 'true' if is_coming_soon else 'false',
          'is_paid': 'true' if is_paid else 'false',
          'limit': 100, 'skip': 0}

或者也许是一个快速的功能来为你做这件事:

encode_bool = lambda x: 'true' if x else 'false'
is_coming_soon, is_paid = False, True
params = {'is_coming_soon': encode_bool(is_coming_soon),
          'is_paid': encode_bool(is_paid),
          'limit': 100, 'skip': 0}

或者我们可以向上移动堆栈并创建一个函数来修改所有布尔值

# Caveat: this only encodes one level of structure.
def encode_boolean_values(kv):
  """ convert bool values to 'true'/'false' strings for json compat """
  enc = lambda x : x if not isinstance(x, bool) else 'true' if x else 'false'
  {k: enc(v) for k,v in kv.items()}

is_coming_soon, is_paid = False, True
params = {'is_coming_soon': is_coming_soon,
          'is_paid': is_paid,
          'limit': 100, 'skip': 0}
params = encode_boolean_values(params)

注意:您可以使用 json.dumps() 代替三元。我使用三元将 Null 折叠为 False 而不是将其设为“null”

【讨论】:

    【解决方案3】:

    requests 有一个助手 kwarg json 正是这样做的。

    你应该会写

    params = {'is_coming_soon': False, 'is_paid': True, 'limit': 100, 'skip': 0}
    headers = {'content-type': 'application/json'}
    response = requests.get(url=url, headers=headers, params=params)
    

    作为

    data = {'is_coming_soon': False, 'is_paid': True, 'limit': 100, 'skip': 0}
    response = requests.get(url, json=data)
    

    改为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-10
      • 1970-01-01
      • 1970-01-01
      • 2021-05-23
      • 2021-05-04
      • 2018-04-21
      相关资源
      最近更新 更多