Python接口自动化浅析requests请求封装原理

news2024/9/20 6:08:20

以下主要介绍如何封装请求

还记得我们之前写的get请求、post请求么?

大家应该有体会,每个请求类型都写成单独的函数,代码复用性不强。

接下来将请求类型都封装起来,自动化用例都可以用这个封装的请求类进行请求

将常用的get、post请求封装起来

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

import requests

class RequestHandler:

    def get(self, url, **kwargs):

        """封装get方法"""

        # 获取请求参数

        params = kwargs.get("params")

        headers = kwargs.get("headers")

        try:

            result = requests.get(url, params=params, headers=headers)

            return result

        except Exception as e:

            print("get请求错误: %s" % e)

    def post(self, url, **kwargs):

        """封装post方法"""

        # 获取请求参数

        params = kwargs.get("params")

        data = kwargs.get("data")

        json = kwargs.get("json")

        try:

            result = requests.post(url, params=params, data=data, json=json)

            return result

        except Exception as e:

            print("post请求错误: %s" % e)

    def run_main(self, method, **kwargs):

        """

        判断请求类型

        :param method: 请求接口类型

        :param kwargs: 选填参数

        :return: 接口返回内容

        """

        if method == 'get':

            result = self.get(**kwargs)

            return result

        elif method == 'post':

            result = self.post(**kwargs)

            return result

        else:

            print('请求接口类型错误')

if __name__ == '__main__':

    # 以下是测试代码

    # get请求接口

    url = 'https://api.apiopen.top/getJoke?page=1&count=2&type=video'

    res = RequestHandler().get(url)

    # post请求接口

    url2 = 'http://127.0.0.1:8000/user/login/'

    payload = {

        "username": "vivi",

        "password": "123456"

    }

    res2 = RequestHandler().post(url2,json=payload)

    print(res.json())

    print(res2.json())

请求结果如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

'message': '成功!',

'result': [{'sid': '31004305',

'text': '羊:师傅,理个发,稍微修一下就行',

'type': 'video',

'thumbnail': 'http://wimg.spriteapp.cn/picture/2020/0410/5e8fbf227c7f3_wpd.jpg',

'video': 'http://uvideo.spriteapp.cn/video/2020/0410/5e8fbf227c7f3_wpd.mp4',

'images': None,

'up': '95',

'down': '1',

'forward': '0',

'comment': '25',

'uid': '23189193',

'name': '青川小舟',

'header': 'http://wimg.spriteapp.cn/profile/large/2019/12/24/5e01934bb01b5_mini.jpg',

'top_comments_content':None,

'top_comments_voiceuri': None,

'top_comments_uid': None,

'top_comments_name': None,

'top_comments_header': None,

'passtime': '2020-04-12 01:43:02'},

{'sid': '30559863',

'text': '机器人女友,除了不能生孩子,其他的啥都会,价格239000元',

'type': 'video',

'thumbnail': 'http://wimg.spriteapp.cn/picture/2020/0306/5e61a41172a1b_wpd.jpg',

'video': 'http://uvideo.spriteapp.cn/video/2020/0306/5e61a41172a1b_wpd.mp4',

'images': None, 'up': '80', 'down': '6',

'forward': '3',

'comment': '20',

'uid': '23131273',

'name': '水到渠成',

'header': 'http://wimg.spriteapp.cn/profile/large/2019/07/04/5d1d90349cd1a_mini.jpg',

'top_comments_content': '为游戏做的秀',

'top_comments_voiceuri': '',

'top_comments_uid': '10250040',

'top_comments_name': '不得姐用户',

'top_comments_header': 'http://wimg.spriteapp.cn/profile',

'passtime': '2020-04-11 20:43:49'}]}

{'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6InZpdmkiLCJleHAiOjE1ODY4NTc0MzcsImVtYWlsIjoidml2aUBxcS5jb20ifQ.k6y0dAfNU2o9Hd9LFfxEk1HKgczlQfUaKE-imPfTsm4',

'user_id': 1,

 'username': 'vivi'}

这样就完美了吗,no,no,no。

以上代码痛点如下:

代码量大:只是封装了get、post请求,加上其他请求类型,代码量较大;

缺少会话管理:请求之间如何保持会话状态。

我们再来回顾下get、post等请求源码,看下是否有啥特点。

get请求源码:

1

2

3

4

5

6

7

8

9

10

11

def get(url, params=None, **kwargs):

    r"""Sends a GET request.

    :param url: URL for the new :class:`Request` object.

    :param params: (optional) Dictionary, list of tuples or bytes to send

        in the query string for the :class:`Request`.

    :param \*\*kwargs: Optional arguments that ``request`` takes.

    :return: :class:`Response <Response>` object

    :rtype: requests.Response

    """

    kwargs.setdefault('allow_redirects', True)

    return request('get', url, params=params, **kwargs)

post请求源码:

1

2

3

4

5

6

7

8

9

10

11

def post(url, data=None, json=None, **kwargs):

    r"""Sends a POST request.

    :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 data to send in the body of the :class:`Request`.

    :param \*\*kwargs: Optional arguments that ``request`` takes.

    :return: :class:`Response <Response>` object

    :rtype: requests.Response

    """

    return request('post', url, data=data, json=json, **kwargs)

仔细研究下,发现get、post请求返回的都是request函数。

再来研究下request源码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

def request(method, url, **kwargs):

    """Constructs and sends a :class:`Request <Request>`.

    :param method: method for the new :class:`Request` object.

    :param url: URL for the new :class:`Request` object.

    :param params: (optional) Dictionary, list of tuples or bytes to send

        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) A JSON serializable Python object 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 ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.

        ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``

        or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string

        defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers

        to add for the file.

    :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.

    :param timeout: (optional) How many seconds 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) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.

    :type allow_redirects: bool

    :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.

    :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 stream: (optional) if ``False``, the response content will be immediately downloaded.

    :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.

    :return: :class:`Response <Response>` object

    :rtype: requests.Response

    Usage::

      >>> import requests

      >>> req = requests.request('GET', 'https://httpbin.org/get')

      <Response [200]>

    """

    # By using the 'with' statement we are sure the session is closed, thus we

    # avoid leaving sockets open which can trigger a ResourceWarning in some

    # cases, and look like a memory leak in others.

    with sessions.Session() as session:

        return session.request(method=method, url=url, **kwargs)

源码看起来很长,其实只有三行,大部分是代码注释。

从源码中可以看出,不管是get还是post亦或其他请求类型,最终都是调用request函数。

既然这样,我们可以不像之前那样,在类内定义get方法、post方法,而是定义一个通用的方法

直接调用request函数

看起来有点绕,用代码实现就清晰了。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

import requests

class RequestHandler:

    def __init__(self):

        """session管理器"""

        self.session = requests.session()

    def visit(self, method, url, params=None, data=None, json=None, headers=None, **kwargs):

        return self.session.request(method,url, params=params, data=data, json=json, headers=headers,**kwargs)

    def close_session(self):

        """关闭session"""

        self.session.close()

if __name__ == '__main__':

    # 以下是测试代码

    # post请求接口

    url = 'http://127.0.0.1:8000/user/login/'

    payload = {

        "username": "vivi",

        "password": "123456"

    }

    req = RequestHandler()

    login_res = req.visit("post", url, json=payload)

    print(login_res.text)

响应结果:

1

2

3

4

5

{

    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6InZpdmkiLCJleHAiOjE1ODY4Njk3ODQsImVtYWlsIjoidml2aUBxcS5jb20ifQ.OD4HIv8G0HZ_RCk-GTVAZ9ADRjwqr3o0E32CC_2JMLg",

    "user_id": 1,

    "username": "vivi"

}

这次请求封装简洁实用,当然小伙伴们也可以根据自己的需求自行封装。

​现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:485187702【暗号:csdn11】

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!【100%无套路免费领取】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1304612.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么现在招聘C++程序员这么难?

为什么现在招聘C程序员这么难&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「C的资料从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&#xff01;&#x…

mars3d加载arcgis发布的服务,⽀持4523坐标

问题 1.从这个服务地址加载&#xff0c;具体在哪⾥去转坐标呢&#xff1f; 加个 usePreCachedTilesIfAvailable&#xff1a;false 参数即可 坐标系为4490的arcgis影像服务图层&#xff0c;配置后瓦片加载不出来&#xff0c;没报错 甚至可以跳转 没有看出问题&#xff0c;或者测…

SD-WAN跨国网络加速的原理

许多企业需要在全球范围内高效传输和交流数据&#xff0c;然而&#xff0c;跨国网络连接面临着多种挑战&#xff0c;如网络延迟、拥塞和数据包丢失&#xff0c;这些问题可能会显著降低企业的运作效率和客户体验。为了克服这些问题&#xff0c;越来越多的企业正在采用SD-WAN跨国…

Java毕业设计——vue+SpringBoot汽车销售管理系统

项目介绍 本项目基于spring boot以及Vue开发&#xff0c;前端实现基于PanJiaChen所提供的开源后台项目vue-element-admin改造。 针对汽车销售提供客户信息、车辆信息、订单信息、销售人员管理、财务报表等功能&#xff0c;提供经理和销售两种角色进行管理。 技术栈 前端 Vue…

使用Java将图片添加到Excel的几种方式

1、超链接 使用POI&#xff0c;依赖如下 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency>Java代码如下,运行该程序它会在桌面创建ImageLinks.xlsx文件。 …

(七)函数

目录 1. 函数的概念 2. 库函数 2.1 标准库和头文件 2.2 库函数的使用方法 2.2.1 功能 2.2.2 头文件包含 2.2.3 库函数文档的一般格式 3. 自定义函数 3.1 函数的语法形式 4. 形参和实参 4.1 实参 4.2 形参 4.3 实参和形参的关系 5. return 语句 6. 数组做函数参数…

python将资源打包进exe

前言 之前py打包的exe一直是不涉及图片等资源的&#xff0c;直到我引入图片后打包&#xff0c;再双击exe发现直接提示未找到资源。 分析 我py代码中的图片引入使用的是项目相对路径&#xff0c;打包时pyinstaller只会引入py模块&#xff0c;这种路径引入的资源其实是不会打包…

生成式模型对比:扩散模型、GAN 与 VAE

引言 深度生成式模型应用于图像、音频、视频合成和自然语言处理等不同领域。随着深度学习技术的快速发展&#xff0c;近年来不同的深度生成模型出现了爆炸式的增长。这导致人们越来越有兴趣比较和评估这些模型的性能和对不同领域的适用性。在 本文中&#xff0c;我们的目标是…

RCG Self-conditioned Image Generation via Generating Representations

RCG: Self-conditioned Image Generation via Generating Representations TL; DR&#xff1a;将图像的无监督表征作为&#xff08;自&#xff09;条件&#xff08;而非是将文本 prompt 作为条件&#xff09;&#xff0c;生成与原图语义内容一致的多样且高质量结果。视觉训练能…

如何在Android中旋转屏幕时避免重新绘制Activity

如何在Android中旋转屏幕时避免重新绘制Activity 在Android开发中&#xff0c;设备旋转通常导致当前活动&#xff08;Activity&#xff09;被销毁并重新创建&#xff0c;这可能导致用户界面重置和不必要的资源重新加载。然而&#xff0c;有时我们希望避免这种行为&#xff0c;…

3.4_3GBN课后题的思考

首先思考最大平均数据传输速率&#xff0c;看到是GBN协议&#xff0c;无法直接带入信道带宽&#xff1b; 其次比较RRT传输时延和信道带宽传输所有数据的时间 把图中划分为三个公式分别为abc 1.a是1000个窗口尺寸&#xff0c;每个尺寸抖音1000字节数据帧&#xff0c;除以信道带宽…

邮件营销软件:10个创新邮件策略,持续提升投资回报(二)

在上一篇文章中&#xff0c;我们了解到内容、个性化和适当的策略有助于在增加邮件营销中客户的参与度。在这篇文章中&#xff0c;我们将深入研究客户行为、自动化和评估等方面。 1、根据客户行为发送电子邮件 从购买到放弃购物车&#xff0c;客户的行为可能千差万别。跟踪这…

胡桃工具箱 原神多功能工具箱

胡桃工具箱 原神胡桃工具箱是一款非常实用的游戏工具辅助软件&#xff0c;可以为用户们提供优质的原神游戏工具&#xff0c;体验更精彩的游戏辅助&#xff0c;提供帧率解锁游戏功能&#xff0c;包括数据查询、游戏详解以及各种实用的功能。 安装使用 1.获取胡桃工具箱 请点击…

linux sed命令删除一行/多行_sed删除第一行/linux删除文件某一行

sed系列文章 linux常用命令(9)&#xff1a;sed命令(编辑/替换/删除文本)linux sed命令删除一行/多行_sed删除第一行/linux删除文件某一行 文章目录 sed系列文章一、sed删除某一行内容/删除最后一行二、sed删除多行三、扩展3.1、-i命令 本文主要讲解如何删除txt文件中的某一行内…

瓶装饮用水行业分析:全国市场产量约4789万吨

水根据自身的硬度首先分为软水和硬水两种。水的硬度是指溶解在水中的盐类物质的含量&#xff0c;也就是钙盐与镁盐的含量&#xff0c;硬度单位是ppm&#xff0c;1ppm代表水中碳酸钙含量1毫克/升(mg/L)。低于142的水称为软水&#xff0c;高于285ppm的水称为硬水&#xff0c;介于…

【PTA刷题】 求子串(代码+详解)

【PTA刷题】 求子串(代码详解) 题目 请编写函数&#xff0c;求子串。 函数原型 char* StrMid(char *dst, const char *src, int idx, int len);说明&#xff1a;函数取源串 src 下标 idx 处开始的 len 个字符&#xff0c;保存到目的串 dst 中&#xff0c;函数值为 dst。若 len…

传输层—UDP—校验和

传输层—UDP—校验和 学习一个协议&#xff0c;当然要掌握协议的特性&#xff0c;还需要理解协议报文格式。 UDP UDP 基本特点&#xff1a;无连接、不可靠传输、面向数据报、全双工 UDP报头包含&#xff1a;源端口、目的端口、UDP报文长度、校验和。 UDP载荷中&#xff1a…

微信小程序开始收取短剧保证金

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 从多位短剧从业者处获悉&#xff0c;今日陆续收到微信公众平台发布的保证金缴纳通知&#xff0c;缴费金额从100-1000不等。 有的需要缴纳1000&#xff0c;而有的只需缴纳100元。这个和你GMV来决…

微信小程序:上传图片到别的域名文件下

效果 wxml <!-- 上传照片 --> <view class"addbtn"><view classpic name"fault_photo" wx:for"{{imgs}}" wx:for-item"item" wx:key"*this"><image classweui-uploader_img src"{{item}}"…