首頁 > 軟體

Python介面自動化之request請求封裝原始碼分析

2022-06-16 18:02:20

前言:

我們在做自動化測試的時候,大家都是希望自己寫的程式碼越簡潔越好,程式碼重複量越少越好。那麼,我們可以考慮將request的請求型別(如:Get、Post、Delect請求)都封裝起來。這樣,我們在編寫用例的時候就可以直接進行請求了。

1. 原始碼分析

我們先來看一下Get、Post、Delect等請求的原始碼,看一下它們都有什麼特點。

(1)Get請求原始碼

	def get(self, url, **kwargs):
		r"""Sends a GET request. Returns :class:`Response` object.
		:param url: URL for the new :class:`Request` object.
	    :param **kwargs: Optional arguments that ``request`` takes.
	    :rtype: requests.Response
	     """
		
		kwargs.setdefault('allow_redirects', True)
		return self.request('GET', url, **kwargs) 

(2)Post請求原始碼

	def post(self, url, data=None, json=None, **kwargs):
		r"""Sends a POST request. Returns :class:`Response` object.
		:param url: URL for the new :class:`Request` object.
	    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
		object to send in the body of the :class:`Request`.
		:param json: (optional) json to send in the body of the :class:`Request`.
		:param **kwargs: Optional arguments that ``request`` takes.
		:rtype: requests.Response
		"""
		return self.request('POST', url, data=data, json=json, **kwargs)  

(3)Delect請求原始碼

    def delete(self, url, **kwargs):
        r"""Sends a DELETE request. Returns :class:`Response` object.
        :param url: URL for the new :class:`Request` object.
        :param **kwargs: Optional arguments that ``request`` takes.
        :rtype: requests.Response
        """
        return self.request('DELETE', url, **kwargs)

(4)分析結果

我們發現,不管是Get請求、還是Post請求或者是Delect請求,它們到最後返回的都是request函數。那麼,我們再去看一看request函數的原始碼。

	def request(self, method, url,
	        params=None, data=None, headers=None, cookies=None, files=None,
	        auth=None, timeout=None, allow_redirects=True, proxies=None,
	        hooks=None, stream=None, verify=None, cert=None, json=None):
	    """Constructs a :class:`Request <Request>`, prepares it and sends it.
	    Returns :class:`Response <Response>` object.
	
	    :param method: method for the new :class:`Request` object.
	    :param url: URL for the new :class:`Request` object.
	    :param params: (optional) Dictionary or bytes to be sent in the query
	        string for the :class:`Request`.
	    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
	        object to send in the body of the :class:`Request`.
	    :param json: (optional) json to send in the body of the
	        :class:`Request`.
	    :param headers: (optional) Dictionary of HTTP Headers to send with the
	        :class:`Request`.
	    :param cookies: (optional) Dict or CookieJar object to send with the
	        :class:`Request`.
	    :param files: (optional) Dictionary of ``'filename': file-like-objects``
	        for multipart encoding upload.
	    :param auth: (optional) Auth tuple or callable to enable
	        Basic/Digest/Custom HTTP Auth.
	    :param timeout: (optional) How long to wait for the server to send
	        data before giving up, as a float, or a :ref:`(connect timeout,
	        read timeout) <timeouts>` tuple.
	    :type timeout: float or tuple
	    :param allow_redirects: (optional) Set to True by default.
	    :type allow_redirects: bool
	    :param proxies: (optional) Dictionary mapping protocol or protocol and
	        hostname to the URL of the proxy.
	    :param stream: (optional) whether to immediately download the response
	        content. Defaults to ``False``.
	    :param verify: (optional) Either a boolean, in which case it controls whether we verify
	        the server's TLS certificate, or a string, in which case it must be a path
	        to a CA bundle to use. Defaults to ``True``.
	    :param cert: (optional) if String, path to ssl client cert file (.pem).
	        If Tuple, ('cert', 'key') pair.
	    :rtype: requests.Response
	    """
	    # Create the Request.
	    req = Request(
	        method=method.upper(),
	        url=url,
	        headers=headers,
	        files=files,
	        data=data or {},
	        json=json,
	        params=params or {},
	        auth=auth,
	        cookies=cookies,
	        hooks=hooks,
	    )
	    prep = self.prepare_request(req)
	    proxies = proxies or {}
	    settings = self.merge_environment_settings(
	        prep.url, proxies, stream, verify, cert
	    )
	    # Send the request.
	    send_kwargs = {
	        'timeout': timeout,
	        'allow_redirects': allow_redirects,
	    }
	    send_kwargs.update(settings)
	    resp = self.send(prep, **send_kwargs)
	    return resp    

從request原始碼可以看出,它先建立一個Request,然後將傳過來的所有引數放在裡面,再接著呼叫self.send(),並將Request傳過去。這裡我們將不在分析後面的send等方法的原始碼了,有興趣的同學可以自行了解。

分析完原始碼之後發現,我們可以不需要單獨在一個類中去定義Get、Post等其他方法,然後在單獨呼叫request。其實,我們直接呼叫request即可。

2. requests請求封裝

程式碼範例:

	import requests
	class RequestMain:
	    def __init__(self):
	        """
	        session管理器
	        requests.session(): 維持對談,跨請求的時候儲存引數
	        """
	        # 範例化session
	        self.session = requests.session()
	    def request_main(self, method, url, params=None, data=None, json=None, headers=None, **kwargs):
	        """
	        :param method: 請求方式
	        :param url: 請求地址
	        :param params: 字典或bytes,作為引數增加到url中         
			:param data: data型別傳參,字典、位元組序列或檔案物件,作為Request的內容
	        :param json: json傳參,作為Request的內容
	        :param headers: 請求頭,字典
	        :param kwargs: 若還有其他的引數,使用可變引數字典形式進行傳遞
	        :return:
	        """
	
	        # 對異常進行捕獲
	        try:
	            """
	            
	            封裝request請求,將請求方法、請求地址,請求引數、請求頭等資訊入參。
	            注 :verify: True/False,預設為True,認證SSL證書開關;cert: 本地SSL證書。如果不需要ssl認證,可將這兩個入參去掉
	            """
	            re_data = self.session.request(method, url, params=params, data=data, json=json, headers=headers, cert=(client_crt, client_key), verify=False, **kwargs)
	        # 例外處理 報錯顯示具體資訊
	        except Exception as e:
	            # 列印異常
	            print("請求失敗:{0}".format(e))
	        # 返回響應結果
	        return re_data
	if __name__ == '__main__':
	    # 請求地址
	    url = '請求地址'
	    # 請求引數
	    payload = {"請求引數"}
	    # 請求頭
	    header = {"headers"}
	    # 範例化 RequestMain()
	    re = RequestMain()
	    # 呼叫request_main,並將引數傳過去
	    request_data = re.request_main("請求方式", url, json=payload, headers=header)
	    # 列印響應結果
	    print(request_data.text)  

 :如果你調的介面不需要SSL認證,可將certverify兩個引數去掉。

3. 總結

本文簡單的介紹了Python介面自動化之request請求封裝

到此這篇關於Python介面自動化之request請求封裝原始碼分析的文章就介紹到這了,更多相關Python request 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com