并发登录是压测比较高频的一个测试项,用python写登录并发其实并不难,首先你有个账号的csv,然后设置并发量进行请求就可以了。
编辑器 VScode
VSCode 全称 Visual Studio Code,是微软出的一款轻量级代码编辑器,免费、开源而且功能强大。
这次主要是写一个账号并发登陆,成功后导出tokens.csv
请求方式: POST;
参数: username, password;
最终产出2个文件
- index.py: 执行文件
- tokens.csv: 导出获取的所有账号
需要账号accounts.csv
- accounts.csv:并发登陆所需要的账号; (账号,密码)
yyh1, 123456
yyh2, 123456
项目依赖库
# 协程
import asyncio
# 用于http请求
import aiohttp
Python和Pip版本
pip 23.2.1
Python 3.11.7
新建index.py文件-开始编码
1.请求url;请求参数;自定义头部
# 请求地址
url = 'https:xxx.cn/login'
# 自定义头部_我们的项目用的是json方式
headers = {
'Content-Type': 'application/json'
}
2.打开accounts.csv并把请求参数存到数组中
import os
# CSV文件路径
account_csv_file = os.path.join(os.path.dirname(__file__), 'accounts.csv')
# 读取CSV文件,并动态把参数存入data数组中
with open(account_csv_file, newline='') as file:
reader = csv.reader(file)
# 使用 islice 获取前 并发数相同的 行
concurrent_rows = list(itertools.islice(reader, threadsNum))
# 把请求参数存入data中
data = []
for row in concurrent_rows:
# 提取账号信息,并构建请求数据
data.append({
'username': row[0],
'password': '123456',
'enctype': 'TEXT'
})
3.根据data的数组参数创建多个线程
async with aiohttp.ClientSession() as session:
tasks = []
for i in range(threadsNum):
task = asyncio.ensure_future(send_post_request(session, data[i]))
tasks.append(task)
# 线程准备完毕了,设置开始时间
start_time = time.time()
# 拿到所有请求的结果
results = await asyncio.gather(*tasks)
4.写请求send_post_request方法
# 请求地址
url = 'https:xxx.cn/login'
# 自定义头部_我们的项目用的是json方式
headers = {
'Content-Type': 'application/json'
}
# 请求超时时间
timeout = 60
# 成功数量
success_count = 0
# 导出csv数组
tokensCsv = []
def send_post_request(session,data):
global url,headers,timeout,exportCsv,success_count
try:
async with session.post(url, json=data, headers=headers, timeout=timeout) as response:
res = await response.json()
if res['status'] == 100:
# 成功数量加1
success_count += 1
# 把成功的结果存到数组中,后续导出csv
exportCsv.append(res['data'])
return res['data']
else:
print('接口错误', res['error'], data)
except Exception as e:
print(f"其它错误: {e}")
合并所有片段
# 1.用到的依赖
import csv
import os
import itertools
import time
# 协程
import asyncio
# http请求
import aiohttp
# 2.全局变量定义;
# 请求地址
url = 'https:xxx.cn/login'
# 自定义头部
headers = {
'Content-Type': 'application/json'
}
# 导出的tokens数组
tokensCsv = []
# 定义并发线程数;这里并发10个;
threadsNum = 10
# 超时时间设置
timeout = 60
# 开始时间
start_time = 0
# 成功数量
success_count = 0
# 3.定义请求方法
def send_post_request(session,data):
global url,headers,timeout,exportCsv,success_count
try:
async with session.post(url, json=data, headers=headers, timeout=timeout) as response:
res = await response.json()
if res['status'] == 100:
success_count += 1
# print('接口成功', res['data'])
exportCsv.append(res['data'])
return res['data']
else:
print('接口错误', res['error'], data)
except Exception as e:
print(f"其它错误: {e}")
# 4.定义并发方法
async def main():
global start_time
# 读取CSV文件
with open(csv_file, newline='') as file:
reader = csv.reader(file)
# 使用 islice 截取账号与并发数相同的行
concurrent_rows = list(itertools.islice(reader, threadsNum))
# 把请求的参数存到数组中
data = []
for row in concurrent_rows:
# 提取账号信息,并构建请求数据
data.append({
'username': row[0],
'password': '123456',
'enctype': 'TEXT'
})
# 创建协程
async with aiohttp.ClientSession() as session:
# 把要并发的任务存起来
tasks = []
for i in range(threadsNum):
task = asyncio.ensure_future(send_post_request(session, data[i]))
tasks.append(task)
# 线程准备完毕了记录开始时间
start_time = time.time()
results = await asyncio.gather(*tasks)
# 全部执行完毕后,打印消息
printInfo()
# 打印消息后, 导出tokens数组
exportTokens()
# 5.调用执行
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
# 6.打印消息方法
def printInfo():
global start_time,success_count,threadsNum
# 总运行时间
total_time = time.time() - start_time # 计算总运行时间(秒)
tps = success_count / total_time # 计算TPS(每秒成功事务数)
print(f"请求总数: {threadsNum}")
print(f"成功总数: {success_count}")
print(f"失败总数: {threadsNum - success_count}")
print(f"TPS: {tps:.2f}")
# print(f"exportCsv: {exportCsv}")
print(f"用时: {int(total_time * 1000)}ms")
# 7导出tokens数组方法
def exportTokens():
global exportCsv
with open('tokens.csv', mode='w', newline='') as file:
writer = csv.writer(file)
for data in exportCsv:
writer.writerow([data['accessToken'], data['user']['id'],data['user']['name']])
执行
- vsCode右键文件选择在集成终端中打开
- 在终端输入: python index.py