[Python] Python接口自动化之request请求封装源码分析

2141 2
小明Python 2023-1-31 14:47:35 | 显示全部楼层 |阅读模式
一. 源码分析

我们先来看一下Get、Post、Delect等请求的源码,看一下它们都有什么特点。

(1)Get请求源码

  1. def get(self, url, **kwargs):
  2.                 r"""Sends a GET request. Returns :class:`Response` object.
  3.                 :param url: URL for the new :class:`Request` object.
  4.             :param \*\*kwargs: Optional arguments that ``request`` takes.
  5.             python 学习交流群:748989764
  6.             :rtype: requests.Response
  7.              """
  8.                
  9.                 kwargs.setdefault('allow_redirects', True)
  10.                 return self.request('GET', url, **kwargs)
复制代码

(2)Post请求源码

  1. def post(self, url, data=None, json=None, **kwargs):
  2.                 r"""Sends a POST request. Returns :class:`Response` object.
  3.                 :param url: URL for the new :class:`Request` object.
  4.             :param data: (optional) Dictionary, list of tuples, bytes, or file-like
  5.                 object to send in the body of the :class:`Request`.
  6.                 :param json: (optional) json to send in the body of the :class:`Request`.
  7.                 :param \*\*kwargs: Optional arguments that ``request`` takes.
  8.                 :rtype: requests.Response
  9.                 """
  10.                 return self.request('POST', url, data=data, json=json, **kwargs)  
复制代码

(3)Delect请求源码

  1.     def delete(self, url, **kwargs):
  2.         r"""Sends a DELETE request. Returns :class:`Response` object.
  3.         :param url: URL for the new :class:`Request` object.
  4.         :param \*\*kwargs: Optional arguments that ``request`` takes.
  5.         :rtype: requests.Response
  6.         """
  7.         return self.request('DELETE', url, **kwargs)
复制代码


(4)分析结果

我们发现,不管是Get请求、还是Post请求或者是Delect请求,它们到最后返回的都是request函数。那么,我们再去看一看request函数的源码。

  1. def request(self, method, url,
  2.                 params=None, data=None, headers=None, cookies=None, files=None,
  3.                 auth=None, timeout=None, allow_redirects=True, proxies=None,
  4.                 hooks=None, stream=None, verify=None, cert=None, json=None):
  5.             """Constructs a :class:`Request <Request>`, prepares it and sends it.
  6.             Returns :class:`Response <Response>` object.
  7.        
  8.             :param method: method for the new :class:`Request` object.
  9.             :param url: URL for the new :class:`Request` object.
  10.             :param params: (optional) Dictionary or bytes to be sent in the query
  11.                 string for the :class:`Request`.
  12.             :param data: (optional) Dictionary, list of tuples, bytes, or file-like
  13.                 object to send in the body of the :class:`Request`.
  14.             :param json: (optional) json to send in the body of the
  15.                 :class:`Request`.
  16.             :param headers: (optional) Dictionary of HTTP Headers to send with the
  17.                 :class:`Request`.
  18.             :param cookies: (optional) Dict or CookieJar object to send with the
  19.                 :class:`Request`.
  20.             :param files: (optional) Dictionary of ``'filename': file-like-objects``
  21.                 for multipart encoding upload.
  22.             :param auth: (optional) Auth tuple or callable to enable
  23.                 Basic/Digest/Custom HTTP Auth.
  24.             :param timeout: (optional) How long to wait for the server to send
  25.                 data before giving up, as a float, or a :ref:`(connect timeout,
  26.                 read timeout) <timeouts>` tuple.
  27.             :type timeout: float or tuple
  28.             :param allow_redirects: (optional) Set to True by default.
  29.             :type allow_redirects: bool
  30.             :param proxies: (optional) Dictionary mapping protocol or protocol and
  31.                 hostname to the URL of the proxy.
  32.             :param stream: (optional) whether to immediately download the response
  33.                 content. Defaults to ``False``.
  34.             :param verify: (optional) Either a boolean, in which case it controls whether we verify
  35.                 the server's TLS certificate, or a string, in which case it must be a path
  36.                 to a CA bundle to use. Defaults to ``True``.
  37.             :param cert: (optional) if String, path to ssl client cert file (.pem).
  38.                 If Tuple, ('cert', 'key') pair.
  39.             :rtype: requests.Response
  40.             """
  41.             # Create the Request.
  42.             req = Request(
  43.                 method=method.upper(),
  44.                 url=url,
  45.                 headers=headers,
  46.                 files=files,
  47.                 data=data or {},
  48.                 json=json,
  49.                 params=params or {},
  50.                 auth=auth,
  51.                 cookies=cookies,
  52.                 hooks=hooks,
  53.             )
  54.             prep = self.prepare_request(req)
  55.             proxies = proxies or {}
  56.             settings = self.merge_environment_settings(
  57.                 prep.url, proxies, stream, verify, cert
  58.             )
  59.             # Send the request.
  60.             send_kwargs = {
  61.                 'timeout': timeout,
  62.                 'allow_redirects': allow_redirects,
  63.             }
  64.             send_kwargs.update(settings)
  65.             resp = self.send(prep, **send_kwargs)
  66.             return resp   
复制代码

从request源码可以看出,它先创建一个Request,然后将传过来的所有参数放在里面,再接着调用self.send(),并将Request传过去。这里我们将不在分析后面的send等方法的源码了,有兴趣的同学可以自行了解。


分析完源码之后发现,我们可以不需要单独在一个类中去定义Get、Post等其他方法,然后在单独调用request。其实,我们直接调用request即可。


二. requests请求封装

代码示例:



  1. import requests
  2.         class RequestMain:
  3.             def __init__(self):
  4.                 """
  5.                 session管理器
  6.                 requests.session(): 维持会话,跨请求的时候保存参数
  7.                 """
  8.                 # 实例化session
  9.                 self.session = requests.session()
  10.             def request_main(self, method, url, params=None, data=None, json=None, headers=None, **kwargs):
  11.                 """
  12.                 :param method: 请求方式
  13.                 :param url: 请求地址
  14.                 :param params: 字典或bytes,作为参数增加到url中         
  15.                         :param data: data类型传参,字典、字节序列或文件对象,作为Request的内容
  16.                 :param json: json传参,作为Request的内容
  17.                 :param headers: 请求头,字典
  18.                 :param kwargs: 若还有其他的参数,使用可变参数字典形式进行传递
  19.                 :return:
  20.                 """
  21.                 python 学习交流群:748989764
  22.                 # 对异常进行捕获
  23.                 try:
  24.                     """
  25.                    
  26.                     封装request请求,将请求方法、请求地址,请求参数、请求头等信息入参。
  27.                     注 :verify: True/False,默认为True,认证SSL证书开关;cert: 本地SSL证书。如果不需要ssl认证,可将这两个入参去掉
  28.                     """
  29.                     re_data = self.session.request(method, url, params=params, data=data, json=json, headers=headers, cert=(client_crt, client_key), verify=False, **kwargs)
  30.                 # 异常处理 报错显示具体信息
  31.                 except Exception as e:
  32.                     # 打印异常
  33.                     print("请求失败:{0}".format(e))
  34.                 # 返回响应结果
  35.                 return re_data
  36.         if __name__ == '__main__':
  37.             # 请求地址
  38.             url = '请求地址'
  39.             # 请求参数
  40.             payload = {"请求参数"}
  41.             # 请求头
  42.             header = {"headers"}
  43.             # 实例化 RequestMain()
  44.             re = RequestMain()
  45.             # 调用request_main,并将参数传过去
  46.             request_data = re.request_main("请求方式", url, json=payload, headers=header)
  47.             # 打印响应结果
  48.             print(request_data.text)  
复制代码



注 :如果你调的接口不需要SSL认证,可将cert与verify两个参数去掉。









VIPZephyr 2023-1-31 16:21:54 | 显示全部楼层
感觉自己英语白学
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行