Python【requests】封装自用

Pytest requests 二次封装,灵活进行HTTP请求 —— Python 实践 在自动化测试、接口调试等场景中,requests 是 Python 中非常常用的 HTTP 客户端库。为了提高代码的可维护性与复用性,我们通常会对 requests 进行二次封装。本文将详细介绍如何对 requests 库进行封装,实现一个支持变量替换、日志记录、Allure 报告集成等功能的 HTTP 请求类。 阅读详情

function版

import requests
from random import choice
from time import strftime

ua = ['Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0;',
      'Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;360SE)']

def write_log(*args):
    with open('%s.txt' % strftime('%Y%m%d'), 'a', encoding='utf-8') as f:
        for a in args:
            f.write('%r\n' % a)
        f.write('\n')

def get(url, encode='utf-8', times=10):
    if times < 0:
        return ''
    try:
        r = requests.get(url, headers={'User-Agent': choice(ua)}, timeout=30)
    except Exception as e:
        write_log(url, e, times)
        return get(url, encode, times - 1)
    if r.status_code == 200:
        r.encoding = encode
        return r.text
    else:
        write_log(url, r.status_code, times)
        return get(url, encode, times - 1)

def post(url, data, encode='utf-8', times=10):
    if times < 0:
        return ''
    try:
        r = requests.post(url, headers={'User-Agent': choice(ua)}, data=data, timeout=30)
    except Exception as error:
        write_log(url, data, error, times)
        return post(url, data, encode, times - 1)
    if r.status_code == 200:
        r.encoding = encode
        return r.text
    else:
        write_log(url, data, r.status_code, times)
        return post(url, data, encode, times - 1)

def get_img(url, times=3):
    """下载图片"""
    if times < 0:
        return b''
    try:
        r = requests.get(url, headers={'User-Agent': choice(ua)}, timeout=30)
    except Exception as e:
        write_log(url, e, times)
        return get_img(url, times - 1)
    if r.status_code == 200:
        return r.content
    else:
        write_log(url, r.status_code, times)
        return get_img(url, times - 1)

class版

request . py

from time import time, sleep, strftime
from requests import get, post
from random import choice
from chardet import detect  # 自动检测网页编码
from core.conf import REQUEST as R, Color as C


def write_log(*args, **kwargs):
    C.red(args, kwargs)
    with open('%s.txt' % strftime('%Y%m%d'), 'a', encoding='utf-8') as f:
        for i in args:
            f.write('%r\n' % i)
        for k, v in kwargs.items():
            f.write('%r\t%r\n' % (k, v))
        f.write('\n')


def get_proxies():
    return {}


class Response:
    text = ''

    @classmethod
    def json(cls):
        return dict()


class Request:
    def __init__(self, header=None):
        self.t = time()
        self.headers = header or dict()

    def __del__(self):
        t = (time() - self.t) / 60
        C.yellow('%.2f分钟' % t)

    def get(self, url, times=R.times, **kwargs):
        sleep(choice(list(range(R.sleep))))  # 随机睡眠
        if times < 0:
            return Response()  # 空响应
        self.headers['User-Agent'] = choice(R.ua)
        try:
            r = get(
                url=url,
                headers=self.headers,
                timeout=R.timeout,
                proxies=get_proxies(),
                **kwargs
            )
        except Exception as error:
            write_log(url, error=error, **kwargs)  # 写日志
            return self.get(url, times - 1, **kwargs)
        if r.status_code == 200:
            r.encoding = detect(r.content)['encoding']
            self.headers['Referer'] = url
            return r
        else:
            write_log(url, status_code=r.status_code, **kwargs)  # 写日志
            return self.get(url, times - 1, **kwargs)

    def post(self, url, data, times=R.times, **kwargs):
        sleep(choice(list(range(R.sleep))))  # 随机睡眠
        if times < 0:
            return Response()  # 空响应
        self.headers['User-Agent'] = choice(R.ua)
        try:
            r = post(
                url=url,
                data=data,
                headers=self.headers,
                timeout=R.timeout,
                proxies=get_proxies(),
                **kwargs
            )
        except Exception as error:
            write_log(url, data=data, error=error, **kwargs)  # 写日志
            return self.post(url, data, times - 1, **kwargs)
        if r.status_code == 200:
            r.encoding = detect(r.content)['encoding']
            return r
        else:
            write_log(url, data=data, status_code=r.status_code, **kwargs)  # 写日志
            return self.post(url, data, times - 1, **kwargs)


if __name__ == '__main__':
    r = Request()
    for i in range(2, 4):
        response = r.get('https://blog.youkuaiyun.com/Yellow_python/article/list/%d?' % i)
        C.green(response.url)
        C.cyan(response.encoding)
        C.blue(response.cookies)
        C.purple(response.headers)
        C.darkcyan(response.request)
        C.yellow(response.elapsed)  # 请求时长
        C.underline(r.headers)
        print()

conf . py

class REQUEST:
    ua = [
        'Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0;',  # IE9.0
        'Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.0;Trident/4.0)',  # IE8.0
        'Mozilla/4.0(compatible;MSIE7.0;WindowsNT6.0)',  # IE7.0
        'Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)',  # IE6.0
        'Mozilla/5.0(Macintosh;IntelMacOSX10.6;rv:2.0.1)Gecko/20100101Firefox/4.0.1',  # Firefox4.0.1–MAC
        'Mozilla/5.0(WindowsNT6.1;rv:2.0.1)Gecko/20100101Firefox/4.0.1',  # Firefox4.0.1–Windows
        'Opera/9.80(Macintosh;IntelMacOSX10.6.8;U;en)Presto/2.8.131Version/11.11',  # Opera11.11–MAC
        'Opera/9.80(WindowsNT6.1;U;en)Presto/2.8.131Version/11.11',  # Opera11.11–Windows
        'Mozilla/5.0(Macintosh;IntelMacOSX10_7_0)AppleWebKit/535.11(KHTML,likeGecko)Chrome/17.0.963.56Safari/535.11',
        'Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;Maxthon2.0)',  # 傲游(Maxthon)
        'Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;TencentTraveler4.0)',  # 腾讯TT
        'Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;360SE)',  # 360浏览器
        'Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;TheWorld)',  # 世界之窗(TheWorld)3.x
        'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',
        'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0',
    ]
    sleep = 1  # SLEEP >= 1
    timeout = 10
    times = 10


class MySQL:
    host = 'localhost'
    user = 'root'
    password = 'yellow'
    charset = 'utf8'
    db = 'z' * 3


class Color:
    @classmethod
    def _wrap_colour(cls, colour, *args):
        for a in args:
            print(colour + '{}'.format(a) + '\033[0m')

    @classmethod
    def blue(cls, *args):
        return cls._wrap_colour('\033[94m', *args)

    @classmethod
    def bold(cls, *args):
        return cls._wrap_colour('\033[1m', *args)

    @classmethod
    def cyan(cls, *args):
        return cls._wrap_colour('\033[96m', *args)

    @classmethod
    def darkcyan(cls, *args):
        return cls._wrap_colour('\033[36m', *args)

    @classmethod
    def green(cls, *args):
        return cls._wrap_colour('\033[92m', *args)

    @classmethod
    def purple(cls, *args):
        return cls._wrap_colour('\033[95m', *args)

    @classmethod
    def red(cls, *args):
        return cls._wrap_colour('\033[91m', *args)

    @classmethod
    def underline(cls, *args):
        return cls._wrap_colour('\033[4m', *args)

    @classmethod
    def yellow(cls, *args):
        return cls._wrap_colour('\033[93m', *args)

mysql . py

import pymysql, re
from time import strftime
from core.conf import MySQL as M, Color as C


class Mysql:
    def __init__(self, table):
        self.db = pymysql.connect(M.host, M.user, M.password, charset=M.charset, db=M.db)
        self.cursor = self.db.cursor()
        self.table = table

    def __del__(self):
        self.cursor.close()
        self.db.close()

    def fetchall(self, query):
        self.cursor.execute(query)
        return self.cursor.fetchall()

    def commit(self, sql):
        try:
            self.cursor.execute(sql)
            self.db.commit()
            C.yellow(sql)
        except Exception as error:
            C.red(error, sql)

    def insert(self, dt):
        dt['collect_date'] = strftime('%Y-%m-%d')
        clear = lambda x: re.sub('''[,'"();]+''', ' ', repr(x)).strip()
        ls = [(k, clear(v)) for k, v in dt.items() if v is not None]
        sql = 'INSERT %s (' % self.table + ','.join([i[0] for i in ls]) + \
              ') VALUES (' + ','.join(['%r' % i[1] for i in ls]) + ');'
        self.commit(sql)

    def update(self, dt_update, dt_condition):
        sql = 'UPDATE %s SET ' % self.table + ','.join('%s=%r' % (k, v) for k, v in dt_update.items())\
              + ' WHERE ' + ' AND '.join('%s=%r' % (k, v) for k, v in dt_condition.items()) + ';'
        self.commit(sql)
python对于requests的封装 由于requests是http类接口的核心,因此封装前考虑问题比较多:1.对多种接口类型的支持;2.连接异常时能够重连;3.并发处理的选择;4.使用方便,容易维护;当前并未全部实现,后期会不断完善。重点提一下并发处理的选择:python的并发处理机制由于存在GIL的原因,实现起来并不是很理想,综合考虑多进程、多线程、协程,在不考虑大并发性能测试的前提下使用了多线程-线程池的形式实现。使用的是con... 阅读详情

相关推荐

SeetaFace6人脸活体检测C++代码实现Demo

活体检测是判断人脸图像是来自真人还是来自攻击假体(照片、视频等)的方法。 人脸识别系统存在被伪造攻击的风险。因此需要在人脸识别系统中加入活体检测,验证用户是否为真实活体本人操作,以防止照片、视频、以及三维模型的入侵,从而帮助用户甄别欺诈行为,保障用户的利益。

mickey2007的博客 3481

Python接口自动化之request请求封装

那么,我们可以考虑将request的请求类型(如:Get、Post、Delect请求)都封装起来。从request源码可以看出,它先创建一个Request,然后将传过来的所有参数放在里面,再接着调用self.send(),并将Request传过去。我们发现,不管是Get请求、还是Post请求或者是Delect请求,它们到最后返回的都是request函数。分析完源码之后发现,我们可以不需要单独在一个类中去定义Get、Post等其他方法,然后在单独调用request。(1)Get请求源码。【保证100%免费】

nhb687095的博客 1023

【Unity报错】Unity导入海康SDK 报错 DllNotFoundException: PlayCtrl assembly

2.尝试按网上其他的办法(包括使用depengs查看dll依赖等)1.先检查Plugins文件夹中是否存在PlayCtrl文件。3.如果网上查阅的办法都不能解决,请继续往下看。更换低版本的SDK库文件。

weixin_42968584的博客 1127

python -- requests库封装

requests是基于Python开发的HTTP 库,requests是在urllib的基础上进行了高度的封装,它不仅继承了urllib的所有特性,而且还支持一些其它的特性,比如使用Cookie保持会话、自动确定响应内容的编码等,可以轻而易举地完成浏览器的任何操作。用的比较多的类有:🎈 requests.Request:用于请求发送到服务器🎈 requests.Response:服务器对HTTP请求的响应,可以返回响应码、请求头、请求url,JSON格式的结果等。

qq_42873925的博客 1104

python3.12 在用django5.0创建超级用户时,遇到AttributeError: module ‘hashlib‘ has no attribute ‘pbkdf2_hmac‘的问题

产生问题的原因是python3.12的hashlib没有自带pbkdf2_hmac函数,该函数是加密算法的一种,只要通过别的函数导入pbkdf2_hmac即可。还有一种方法是将django默认使用的pbkdf2_hmac改为hashlib自带的sha2或其他算法返回加密的密码,笔者以后会尝试用此类办法解决问题。2.找到报错文件的位置/usr/local/lib/python3.12/site-packages/django/utils/crypto.py。保存修改的文件,重新执行创建超级用户的命令成功。

weixin_67057943的博客 853

吉比特-笔试

1. 题一:打雷后下雨的概率是80%,而打闪电后下雨的概率是70%,那么即打雷又打闪电后下雨的概率是多少?   答:打雷后下雨和打闪电后下雨都是独立事件,P=1-又打雷又闪电但没下雨的概率= 1 - 0.2 *0.3 = 94%        题二:打雷后下雨的概率是80%,但是没打闪电后下雨的概率是20%,那么打雷了但没打闪电后下雨的概率是多少?答:P=0.8 *0.2 / ( 0.8 *0

naturism的专栏 2497

【Requests】Python封装requests模块

python对requests模块封装

weixin_52358204的博客 1194

Qt Tab Widget 实战:如何打造一个可动态增删的标签页管理器(附完整代码)

本文深入探讨了使用Qt框架中的Tab Widget控件构建动态标签页管理器的实战方法。通过分析动态增删的核心挑战,提供了完整的C++代码示例,涵盖信号槽机制、页面生命周期管理、上下文菜单实现以及状态持久化等关键功能,帮助开发者打造高效、用户友好的桌面应用界面。

bb456的博客 1047

Python接口自动化 ❀ Request库详解和框架封装

接口关联:创建一个extract.yaml文件存放关联数据,使用yaml文件写和读的操作进行接口关联。2、re.findall:匹配多个值,返回列表list,多个值通过下标取值,,没有则返回None。jsonpath.jsonpath,返回的是一个列表,通过下标取值,没有则返回None。1、re.seach:只匹配一个值,通过下标[1]取值,没有匹配到放回None。JsonPath提取(jsonpath只能够提取json格式的数据)正则提取(正则表达式只能提取字符串的数据)

炫酷的腿毛! 3637

openCv +3.4.0 车牌定位(C++版本)

#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc.hpp> #include "opencv2/shape.hpp" using namespace ...

Bamboo265925的博客 2339

【ubuntu】【VirtualBox】VirtualBox无法加载USB移动设备的解决方法(支持U盘启动盘)

提示:测试可用。

联系方式:927632640 2440

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

还记得我们之前写的get请求、post请求么?大家应该有体会,每个请求类型都写成单独的函数,代码复用性不强。接下来将请求类型都封装起来,自动化用例都可以用这个封装的请求类进行请求

软件测试技术交流分享 891

手把手教你学Simulink--基础储能管理场景实例:基于Simulink的锂电池健康状态(SOH)在线评估仿真

本文详细介绍了基于Simulink的锂电池健康状态(SOH)在线评估仿真方法。主要内容包括:1)SOH定义与量化指标(容量SOH、内阻SOH及综合SOH);2)基于Thevenin模型参数辨识和递推最小二乘法(RLS)的在线评估原理;3)100次充放电循环的仿真场景设置;4)Simulink建模步骤(主电路搭建、核心模块实现及信号流连接);5)仿真结果分析,显示SOH评估误差<2%,响应时间45秒,满足在线评估需求;6)提出多参数融合评估、深度学习辅助辨识等优化方向。该方法为储能系统寿命管理提供了有效

MHD0815的博客 182

Requests详解与封装

requests 模块是 python 基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。

Litch_的博客 2645

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

requests的深入刨析及封装调用

说到python发送HTTP请求进行接口自动化测试,脑子里第一个闪过的可能就是requests库了,当然python有很多模块可以发送HTTP请求,包括原生的模块http.client,urllib2等,但由于原生的模块过于复杂,使用繁琐,那么requests库就诞生了,它也是现阶段比较流行的接口自动化测试工具之一。

chengxuyuznguoke的博客 1187

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Python requests请求方法封装

Python requests请求方法封装,post、get、put等

1495

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

python接口测试:封装get和post请求+重新封装requests类

封装get、post请求如下: #!/usr/bin/env python # coding=utf-8 import requests class RunMain: """ 根据传入的URL、请求方式和请求参数来发送请求,并返回requests.models.Response """ def __init__(self): pass ...

放开那只大熊猫 3575

python菜鸟级requests请求封装

分步骤发起requests请求 # 导入requests模块 # 定义一个url,构造一个请求的url url = "http://host/lujing" # 定义参数,创建请求参数 params = { "mobile": "18200004321", "pwd": "123456", } # 修改请求头中的请求客户端 # 反爬...

dianyanzhu6615的博客 1263

Python接口自动化之requests请求封装

在上一篇Python接口自动化测试系列文章:Python接口自动化之Token详解及应用,介绍token基本概念、运行原理及在自动化中接口如何携带token进行访问。 以下主要介绍如何封装请求。 还记得我们之前写的get请求、post请求么? 大家应该有体会,每个请求类型都写成单独的函数,代码复用性不强。 接下来将请求类型都封装起来,自动化用例都可以用这个封装的请求类进行请求,我们将常用的get、post请求封装起来。 importrequests classRequestHandle...

7304

python库封装_python3的requests库二次封装

因为请求API时,需要带token这些,所以requests库每次请求的主机头,需要带上Authorization这个header,且格式为"Bearer xxxxxxxxxx.xxxxxxxxx.xxxxxxx"的形式。 于是索性把get和post, response都封装一下,快~~~Class代码:初始化时,就调用生成token的方法class ReqClient:def __init__(...

weixin_39655377的博客 1137

Python接口自动化之requests请求统一封装

还记得我们之前写的请求、post请求么?大家应该有体会,每个请求类型都写成单独的函数,代码复用性不强。

2301_81967508的博客 946

python requests get请求_Python接口自动化之requests请求封装

——————·今天距2021年253天·——————这是ITester软件测试小栈第114次推文在上一篇Python接口自动化测试系列文章:Python接口自动化之Token详解及应用,介绍token基本概念、运行原理及在自动化中接口如何携带token进行访问。以下主要介绍如何封装请求。还记得我们之前写的get请求、post请求么?大家应该有体会,每个请求类型都写成单独的函数,代码复用性...

weixin_39555951的博客 763

Python爬虫开发:requests库高级封装实践

HTTP请求是网络爬虫的核心技术之一,Python中的requests库因其简洁API成为最受欢迎的HTTP客户端。在实际工程中,直接使用原生requests会遇到编码识别、异常处理、代理管理等共性问题。通过面向对象封装,可以实现请求配置统一管理、自动重试机制、连接池复用等生产级功能。本文以电商爬虫为例,展示如何构建支持智能编码检测(使用chardet库)、指数退避重试、并发控制的请求客户端。这类封装尤其适用于需要处理反爬策略、大规模数据采集的场景,能显著提升爬虫的健壮性和可维护性。

soyo的专栏 1050
上一篇: 爬取并执行本篇优快云博客的代码
下一篇: Python【打印进度条】
小基基o_O
博客等级 码龄9年 4414粉丝 467原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小基基o_O

您的鼓励是我创作的巨大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值