Skip to content

Commit 2d3f0d5

Browse files
committed
bugfix
1 parent a3859af commit 2d3f0d5

File tree

5 files changed

+236
-2
lines changed

5 files changed

+236
-2
lines changed

ONLINE/BAT.py

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
import datetime
4+
import json
5+
import ssl
6+
import unicodedata
7+
from concurrent.futures.thread import ThreadPoolExecutor
8+
9+
import pandas as pd
10+
import numpy as np
11+
import requests
12+
import argparse
13+
14+
# 屏蔽HTTPS证书校验, 忽略安全警告
15+
requests.packages.urllib3.disable_warnings()
16+
context = ssl._create_unverified_context()
17+
18+
19+
def init_param() -> list:
20+
"""
21+
初始化参数, 读取shell命令参数, 自动登录
22+
依次返回httpie_view方式, 线程池, 登录cookie
23+
:rtype: list
24+
"""
25+
parser = argparse.ArgumentParser(description="并发执行接口")
26+
parser.add_argument("-w", "--workers", type=int, choices=choice_nums(1, 65, 1), default=1, help="并发执行线程数, 取值范围[1, 64]")
27+
group = parser.add_mutually_exclusive_group()
28+
group.add_argument("-v", "--view", action="store_true", help="显示请求详细信息")
29+
group.add_argument("-hd", "--header", action="store_true", help="显示请求头")
30+
group.add_argument("-b", "--body", action="store_true", help="显示请求Body")
31+
group.add_argument("-d", "--download", action="store_true", help="显示请求头, 但响应结果保存至TXT")
32+
args = parser.parse_args()
33+
view_param = "-v"
34+
if args.header:
35+
view_param = "-h"
36+
if args.body:
37+
view_param = "-b"
38+
if args.download:
39+
view_param = "-d"
40+
print("参数设置结果: httpie命令方式=[{}], 并发线程数=[{}]".format(view_param, args.workers))
41+
init_executor = ThreadPoolExecutor(max_workers=args.workers)
42+
cookie = auto_login()
43+
return [view_param, init_executor, cookie]
44+
45+
46+
def execute_http(id: int) -> str:
47+
"""
48+
执行excuteUrl.json接口, 返回结果数据
49+
:param id: 接口请求标识性ID数据
50+
:rtype: str
51+
"""
52+
with open("./excuteUrl.json", 'r') as request_data:
53+
request_json = json.load(request_data)
54+
url = request_json['url']
55+
method = request_json['method']
56+
request_headers = handle_json_str_value(request_json['headers'])
57+
request_headers['Cookie'] = init_cookie
58+
request_body = replace_id(request_json['body'], id)
59+
response_body = {
60+
"status": -1,
61+
"msg": "接口执行失败",
62+
"data": "请检查接口是否返回JSON格式的相应数据, 以及抛出未经处理的特殊异常"
63+
}
64+
executeStartTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
65+
try:
66+
response = requests.request(method, url, headers=request_headers, json=request_body, timeout=3, verify=False)
67+
# JSON标准格式
68+
response_body = json.dumps(response.json(), ensure_ascii=False, indent=4)
69+
except Exception as e:
70+
print(e)
71+
executeEndTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
72+
httpie_cmd_str = httpie(url, method, request_headers, request_body)
73+
return "执行命令httpie:\n{}\n当前ID=[{}], executeStartTime=[{}], executeEndTime=[{}]\n响应结果:\n{}".format(httpie_cmd_str, id, executeStartTime, executeEndTime, response_body)
74+
75+
76+
def httpie(url: str, method: str, request_headers: json, request_body: json) -> str:
77+
"""
78+
拼接httpie完整命令
79+
:param url: 接口访问路径
80+
:param method: 请求方式
81+
:param request_headers: 请求头JSON
82+
:param request_body: 请求Body体JSON
83+
:rtype: str
84+
"""
85+
joiner = ' '
86+
cmd = "http"
87+
no_ca = "--verify=no"
88+
param_list = [cmd, no_ca, httpie_view]
89+
param_list.extend([method, url])
90+
for (k, v) in request_headers.items():
91+
if k == "Cookie":
92+
param_list.append("'" + k + ":" + v + "'")
93+
else:
94+
param_list.append(k + ":" + v)
95+
for (k, v) in request_body.items():
96+
if is_number(v):
97+
param_list.append(k + ":=" + v)
98+
else:
99+
param_list.append(k + "=" + v)
100+
return joiner.join(param_list)
101+
102+
103+
def is_number(s: str) -> bool:
104+
"""
105+
:param s: 输入字符串
106+
:rtype: bool
107+
"""
108+
try:
109+
float(s)
110+
return True
111+
except ValueError:
112+
# ValueError为Python的一种标准异常,表示"传入无效的参数"
113+
# 如果引发了ValueError这种异常,不做任何事情(pass:不做任何事情,一般用做占位语句)
114+
pass
115+
try:
116+
# 把一个表示数字的字符串转换为浮点数返回的函数
117+
unicodedata.numeric(s)
118+
return True
119+
except (TypeError, ValueError):
120+
pass
121+
return False
122+
123+
124+
def load_data() -> list:
125+
"""
126+
读取数据文件, 每行为一条数据
127+
:rtype: list
128+
"""
129+
data = pd.read_csv("./ID.csv", header=-1)
130+
data.columns = ['id']
131+
return data['id']
132+
133+
134+
def auto_login() -> str:
135+
"""
136+
自动登录, 获取登录Cookie
137+
:rtype: str
138+
"""
139+
with open("./ssoLogin.json", 'r') as sso_login_request_data:
140+
request_json = json.load(sso_login_request_data)
141+
url = request_json['url']
142+
method = request_json['method']
143+
request_headers = handle_json_str_value(request_json['headers'])
144+
request_body = handle_json_str_value(request_json['body'])
145+
# request_headers = {"Content-Type": "application/json", "HT-app": "6"}
146+
response = requests.request(method, url, headers=request_headers, json=request_body, timeout=3, verify=False)
147+
response_headers = response.headers
148+
# 处理Cookie, 多个Cookie之间使用';'分隔, 否则校验cookie时出现"domain."在高版本中tomcat中报错
149+
# https://blog.csdn.net/w57685321/article/details/84943176
150+
cookie = response_headers.get("set-Cookie").replace(", _r", "; _r").replace(", _a", "; _a")
151+
# JSON标准格式
152+
response_body = json.dumps(response.json(), ensure_ascii=False, indent=4)
153+
print("登录响应Cookie结果: \n{}\n登录响应BODY结果: {}".format(cookie, response_body))
154+
return cookie
155+
156+
157+
def handle_json_str_value(json: json) -> json:
158+
"""
159+
将json的值都变为字符串处理
160+
:param json:
161+
:rtype: json
162+
"""
163+
for (k, v) in json.items():
164+
json[k] = str(v)
165+
return json
166+
167+
168+
def replace_id(json: json, id: int) -> json:
169+
"""
170+
将json的值都变为字符串处理
171+
:param json:
172+
:param id: 目标ID
173+
:rtype: json
174+
"""
175+
for (k, v) in json.items():
176+
if v == "NONE":
177+
json[k] = str(id)
178+
else:
179+
json[k] = str(v)
180+
return json
181+
182+
183+
def choice_nums(start: int, end: int, delta: int) -> list:
184+
"""
185+
返回指定的数组序列
186+
:rtype: list
187+
"""
188+
return np.arange(start, end, delta).tolist()
189+
190+
191+
def main():
192+
# 全局变量
193+
global httpie_view
194+
global executor
195+
global init_cookie
196+
# 首先初始化数据
197+
init = init_param()
198+
httpie_view = init[0]
199+
executor = init[1]
200+
init_cookie = init[2]
201+
# 读取ID数据列表
202+
ids = load_data()
203+
for result in executor.map(execute_http, ids):
204+
print(result)
205+
206+
207+
if __name__ == '__main__':
208+
main()

ONLINE/ID.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
12345

ONLINE/excuteUrl.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"url": "https://localhost:8119/account/sentinel",
3+
"method": "POST",
4+
"headers" : {
5+
"Content-Type": "application/json",
6+
"HT-app": 6
7+
},
8+
"body": {
9+
"subAccountId": "NONE"
10+
}
11+
}

ONLINE/ssoLogin.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"url": "https://sso.testa.huitong.com/api/v100/ssonew/login",
3+
"method": "POST",
4+
"headers": {
5+
"Content-Type": "application/json",
6+
"HT-app": 6
7+
},
8+
"body": {
9+
"phone": "13188880000",
10+
"smsAuthCode": "123456",
11+
"loginType": 0,
12+
"pwd": "ht123456."
13+
}
14+
}

concurrent_test/excuteUrl.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
2-
"url": "http://172.16.10.41:8119/api/v100/user_new/userRole/detail",
2+
"url": "https://localhost:8119/account/sentinel",
33
"method": "POST",
44
"headers" : {
55
"Content-Type": "application/json",
66
"HT-app": 6
77
},
88
"body": {
9-
"subAccountId": 10009984
9+
"subAccountId": 11231095
1010
}
1111
}

0 commit comments

Comments
 (0)