美文网首页
Python requests.post方法中的data与jso

Python requests.post方法中的data与jso

作者: Gavin_c980 | 来源:发表于2019-12-27 16:48 被阅读0次

    遇到问题

    在用requests.post方法测试接口调用时,使用data参数得到Response 400结果;使用json参数得到Response 200。测试代码如下。

    import requests
    import json
    
    url = "https://10.20.32.92:8834/scans"
    accesskey = 'dc9ada34d59'
    secretkey = 'f3b404a433fea25'
    
    header = {
        'X-ApiKeys': 'accessKey={accesskey};secretKey={secretkey}'.format(accesskey=accesskey, secretkey=secretkey),
        'X-API-Token':'0FADA7F5-8903-4686-81F7-ECD0096628EA',
        'Content-type': 'application/json',
        'Accept': 'text/plain'
    }
    
    data = {
        "uuid":"bbd4f805-3966-d464-b2d1-0079e2bcf",
        "settings":{
            "name":"testscan",
            "enabled": "true",
            "text_targets": "ip_list",
            "agent_group_id": []
        }
    }
    
    
    print(requests.post(url, headers=header, data=data, verify=False))
    print(requests.post(url, headers=header, json=data, verify=False))
    

    400与200含义

    • 400 Bad Request --- The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, size too large, invalid request message framing, or deceptive request routing).
    • 200 OK --- Standard response for successful HTTP requests. The actual response will depend on the request method used. In a GET request, the response will contain an entity corresponding to the requested resource. In a POST request, the response will contain an entity describing or containing the result of the action.

    data与json区别

    从requests的官方文档解释中看出:

    • data用于发送form-encoded数据,类似HTML表单
    • json用于发送not form-encoded数据,例如发送字符串。
    • json参数将Content-Type改为application/json
    • json参数自动对传入的参数调用json.dumps()

    从requests源码中的prepare_body函数中可看出针对json参数,修改了Content-Type以及调用json.dumps()的操作。

    这样可能不能很好的理解这两个参数的区别,下面使用https://httpbin.org/post测试,代码如下:

    import requests
    import json
    
    header = {
        'Content-type': 'application/json'
    }
    data = {
        "uuid":"test-uuid",
        "settings":{
            "name":"test-httpbin",
            "enabled": "true",
            "text_targets": "ip_list",
        }
    }
    
    print('\n')
    print('-- [ data = data ] -------------------------------------------')
    r = requests.post("https://httpbin.org/post", data=data)
    print(r.text)
    
    
    print('\n')
    print('-- [ data = json.dumps ] -------------------------------------------')
    r = requests.post("https://httpbin.org/post", data=json.dumps(data))
    print(r.text)
    
    print('\n')
    print('-- [ json = data ] -------------------------------------------')
    r = requests.post("https://httpbin.org/post", json=data)
    print(r.text)
    

    执行结果如下:

    -- [ data = data ] -------------------------------------------
    {
      "args": {},
      "data": "",
      "files": {},
      "form": {
        "settings": [
          "name",
          "enabled",
          "text_targets"
        ],
        "uuid": "test-uuid"
      },
      "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Content-Length": "67",
        "Content-Type": "application/x-www-form-urlencoded",
        "Host": "httpbin.org",
        "User-Agent": "python-requests/2.22.0"
      },
      "json": null,
      "url": "https://httpbin.org/post"
    }
    
    -- [ data = json.dumps ] -------------------------------------------
    {
      "args": {},
      "data": "{\"uuid\": \"test-uuid\", \"settings\": {\"name\": \"test-httpbin\", \"enabled\": \"true\", \"text_targets\": \"ip_list\"}}",
      "files": {},
      "form": {},
      "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Content-Length": "105",
        "Host": "httpbin.org",
        "User-Agent": "python-requests/2.22.0"
      },
      "json": {
        "settings": {
          "enabled": "true",
          "name": "test-httpbin",
          "text_targets": "ip_list"
        },
        "uuid": "test-uuid"
      },
      "url": "https://httpbin.org/post"
    }
    
    -- [ json = data ] -------------------------------------------
    {
      "args": {},
      "data": "{\"uuid\": \"test-uuid\", \"settings\": {\"name\": \"test-httpbin\", \"enabled\": \"true\", \"text_targets\": \"ip_list\"}}",
      "files": {},
      "form": {},
      "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Content-Length": "105",
        "Content-Type": "application/json",
        "Host": "httpbin.org",
        "User-Agent": "python-requests/2.22.0"
      },
      "json": {
        "settings": {
          "enabled": "true",
          "name": "test-httpbin",
          "text_targets": "ip_list"
        },
        "uuid": "test-uuid"
      },
      "url": "https://httpbin.org/post"
    }
    

    从结果可看出data=json.dumps()json=data是等价的。而它们与data=data的差异在于数据存放的字段不同。

    • data=data,数据存放在form字段中
    • json=data,数据存放在datajson字段中

    由此可看出,使用requests.post方法中的data或json参数发送数据时,发送的数据被放到不同的键(form或data/json)下。具体从哪个键取数据,这就看接口的实现方式了。因此,若接口从data/json取数据,而调用requests.post方法时使用data参数发送数据,则会导致接口取出的数据为空,从而返回400状态码。

    补充1:HTTP状态码分类

    HTTP响应状态代码分为五个类别。第一位表示响应的类别,后两位没有分类作用。五个分类如下:

    • 1xx informational response – the request was received, continuing process
    • 2xx successful – the request was successfully received, understood and accepted
    • 3xx redirection – further action needs to be taken in order to complete the request
    • 4xx client error – the request contains bad syntax or cannot be fulfilled
    • 5xx server error – the server failed to fulfill an apparently valid request

    补充2:python字典和Json的区别

    从字符串的表示规则上看,Python字典和JSON非常相似。但是Python字典本身是一个完整的数据结构,可实现其自己的所有算法。

    • json的key只能是字符串;Python字典的key可以是任何可hash对象
    • json的key可以是有序、重复的;Python字典的key不可以重复
    • json的key存在默认值undefined;Python字典key默认没有默认值
    • json的value只能是字符串、浮点数、布尔值或者null,或者它们构成的数组或者对象
    • json访问方式可以是[],也可以是.,遍历方式分in、of;dict的value仅可以下标访问
    • json的字符串强制双引号;Python字典的字符串可以单引号、双引号
    • json里只有数组;Python字典可以嵌套tuple
    • json:true、false、null;python:True、False、None
    • json中文必须是unicode编码,如"\u6211"
    • json的类型是字符串;Python字典的类型是字典

    相关文章

      网友评论

          本文标题:Python requests.post方法中的data与jso

          本文链接:https://www.haomeiwen.com/subject/oamdoctx.html