requests.post()方法中的data参数和json参数

requests.post()
在通过requests.post()进行POST请求时,传入报文的参数有两个,一个是data,一个是json。
常见的form表单可以直接使用data参数进行报文提交,而data的对象则是python中的字典类型;
而在最新爬虫的过程中遇到了一种payload报文,是一种json格式的报文,因此传入的报文对象也应该是格式的;这里有两种方法进行报文提交:

import requests
import json
 
url = "http://httpbin.org/post"
data = {
    "name":"haha",
    "age":18
}
# 1-data需要用json模块转一下
requests.post(url, data=json.dumps(data))
# 2-json参数会自动将字典类型的对象转换为json格式
requests.post(url, json=data)

请求的结果:

{
    "args": {},
    "data": "{
    "name":"haha",
    "age":18
}",
    "files": {},
    "form": {},
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate, br",
        "Cache-Control": "no-cache",
        "Content-Length": "38",
        "Content-Type": "application/json",
        "Host": "httpbin.org",
        "Postman-Token": "4ab45225-e133-4d9d-9a58-30f651fe8af8",
        "User-Agent": "PostmanRuntime/7.28.4",
        "X-Amzn-Trace-Id": "Root=1-616792a5-477ed8535b0b24aa4cc7c177"
    },
    "json": {
        "age": 18,
        "name": "haha"
    },
    "origin": "218.*.*.44",
    "url": "http://httpbin.org/post"
}

解析:

优点:

1. 不需要再用json.dumps做转换传参给data了

2. 也不需要加请求头了:

headers = {
    'Content-Type': 'application/json'
}    

主要是因为源码中这块已经做了该做的事情了

    def prepare_body(self, data, files, json=None):
        """Prepares the given HTTP body data."""

        # Check if file, fo, generator, iterator.
        # If not, run through normal process.

        # Nottin' on you.
        body = None
        content_type = None

        if not data and json is not None:
            # urllib3 requires a bytes-like body. Python 2's json.dumps
            # provides this natively, but Python 3 gives a Unicode string.
            content_type = 'application/json'
            body = complexjson.dumps(json)
            if not isinstance(body, bytes):
                body = body.encode('utf-8')

        is_stream = all([
            hasattr(data, '__iter__'),
            not isinstance(data, (basestring, list, tuple, Mapping))
        ])

        if is_stream:
            try:
                length = super_len(data)
            except (TypeError, AttributeError, UnsupportedOperation):
                length = None

            body = data

            if getattr(body, 'tell', None) is not None:
                # Record the current file position before reading.
                # This will allow us to rewind a file in the event
                # of a redirect.
                try:
                    self._body_position = body.tell()
                except (IOError, OSError):
                    # This differentiates from None, allowing us to catch
                    # a failed `tell()` later when trying to rewind the body
                    self._body_position = object()

            if files:
                raise NotImplementedError('Streamed bodies and files are mutually exclusive.')

            if length:
                self.headers['Content-Length'] = builtin_str(length)
            else:
                self.headers['Transfer-Encoding'] = 'chunked'
        else:
            # Multi-part file uploads.
            if files:
                (body, content_type) = self._encode_files(files, data)
            else:
                if data:
                    body = self._encode_params(data)
                    if isinstance(data, basestring) or hasattr(data, 'read'):
                        content_type = None
                    else:
                        content_type = 'application/x-www-form-urlencoded'

            self.prepare_content_length(body)

            # Add content-type if it wasn't explicitly provided.
            if content_type and ('content-type' not in self.headers):
                self.headers['Content-Type'] = content_type

        self.body = body

不得不赞美一下作者,想的周到了,可是知道的有点晚了

原文地址:https://www.cnblogs.com/yunlongaimeng/p/15405487.html