HTTP测试工具V1.0
介绍
今天来使用 tkinter 写一个爬虫的 http 测试工具,当然市面上也有许多稳定的测试工具可以使用,本次主要的学习 tkinter 界面开发的使用方法以及爬虫的相关的一些基本操作;本来是准备使用 Qt 制作的,但是制作完后发现程序不稳定,经常卡死,最后选择了 tkinter 再开发一个;以下就是我的开发过程,大家谁知道QT为什么会经常卡死,或者有解决方法的可以私聊讨论以下。
界面
大家先看一下界面效果图:
主界面:
辅助功能界面:
一 、Curl 转换 为Python代码功能界面:
二 、 验证码识别界面:
程序功能介绍:
1、支持 http2.0
与 http1.0
进行转换测试;
2、UA
允许 随机生成;
3、忽略 证书验证
;
4、支持 Xpath
解析数据;
5、允许代理测试;
6、允许 身份认证测试;
7、允许阻止 重定向;
8、对于展示结果 可以进行选择;
9、可以使用 Curl 快速生成代码进行访问测试;
10、可以复制转换后的Python代码;
11、支持部分验证码的 检测识别。
使用到的库
import cv2
import ddddocr
import os
import cchardet
import datetime
import fake_useragent
import httpx
import threading
from tkinter import *
from PIL import ImageTk, Image
from curl2py import curlParseTool
from tkinter import filedialog
from tkinter import ttk, scrolledtext, simpledialog
from parsel import Selector
界面 设计
主窗口设计
一、设计多窗口
将三个功能分开设计
tabControl = ttk.Notebook(self.app) # Create Tab Control
http_chkout = ttk.Frame(tabControl) # http 窗口
tabControl.add(http_chkout, text='HTTP')
Curl = ttk.Frame(tabControl)
tabControl.add(Curl, text='CURL')
Yzm = ttk.Frame(tabControl)
tabControl.add(Yzm, text='验证码')
二、 主窗口
设计主要的 HTTP 测试窗口
def http_check(self, http_chkout):
# ----------------- http 测试界面 ------------------ #
chec = ttk.Frame(http_chkout)
chec.grid(column=0, row=0)
# 请求方式列表
self.method = ttk.Combobox(chec, width=8)
self.method['values'] = ('GET', 'POST', 'PUT')
self.method.grid(column=0, row=1)
self.method.current(0) # 设置初始显示值,值为元组['values']的下标
self.method.config(state='readonly') # 设为只读模式
# URL
self.url = ttk.Entry(chec, width=88)
self.url.grid(column=1, row=1, sticky='W')
search = ttk.Button(chec, text="测试", width=10, command=self.search) # 搜索
search.grid(column=2, row=1)
# 状态 states
states = ttk.Frame(http_chkout)
states.grid(column=0, row=1, ipadx=1, sticky=W)
state1 = ttk.Frame(states)
state1.grid(column=0, row=0, pady=10, padx=20, sticky=W)
state2 = ttk.Frame(states)
state2.grid(column=1, row=0, pady=10, padx=20, sticky=W)
state3 = ttk.Frame(states)
state3.grid(column=2, row=0, pady=10, padx=20, sticky=W)
# 上面 三个 框架
Label(state1, text="请求头").grid(column=0, row=0)
add = ttk.Button(state1, text="➕", width=5, command=self.add)
add.grid(column=1, row=0)
del_e = ttk.Button(state1, text="➖", width=5, command=self.dele)
del_e.grid(column=2, row=0)
curl = ttk.Button(state1, text="curl", width=5, command=self.Curl)
curl.grid(column=3, row=0)
self.table_header = ttk.Treeview(state1, show="headings", height=13, columns=("name", "value"))
self.table_header.column("name", width=65, anchor='center')
self.table_header.column("value", width=130, anchor="w")
self.table_header.heading("name", text="name")
self.table_header.heading("value", text="value")
self.table_header.grid(column=0, row=1, columnspan=4, pady=5) # column 列
Label(state2, text="DATA ( param )").grid(column=0, row=0)
self.Data = scrolledtext.ScrolledText(state2, width=33, height=10, wrap=WORD)
self.Data.grid(column=0, row=2)
Label(state2, text="JSON").grid(column=0, row=3)
self.Data = scrolledtext.ScrolledText(state2, width=33, height=10, wrap=WORD)
self.Data.grid(column=0, row=4)
Label(state3, text="特殊选择").grid(column=0, row=0, columnspan=3)
self.http2 = BooleanVar() # HTTP 版本选择
Checkbutton(state3, text="Http2.0 (默认1.0)", variable=self.http2).grid(column=0, row=1, sticky=W, columnspan=3)
self.ua = BooleanVar() # 随机 UA
ua = Checkbutton(state3, text="随机UA", variable=self.ua)
ua.select()
ua.grid(column=0, row=2, sticky=W, columnspan=3)
self.Ajax = BooleanVar()
Checkbutton(state3, text="Ajax XMLHttp", variable=self.Ajax).grid(column=0, row=3, sticky=W, columnspan=3)
self.verify = BooleanVar()
verify = Checkbutton(state3, text="忽略证书验证", variable=self.verify)
verify.select()
verify.grid(column=0, row=4, sticky=W, columnspan=3)
self.Xpath = BooleanVar()
Checkbutton(state3, text="XPATH :", variable=self.Xpath, command=self.small_xpath).grid(column=0, row=5,
sticky=W)
self.xpath = ttk.Entry(state3, width=20)
self.xpath.insert(0, "如: //div[@id='xxxx']")
self.xpath.configure(state='readonly')
self.xpath.grid(column=1, row=5, sticky=W, columnspan=2)
Label(state3, text="TimeOut: ").grid(column=0, row=6, sticky=W)
self.TimeOut = Spinbox(state3, from_=3, to=30, width=5)
self.TimeOut.grid(column=1, row=6, sticky=W)
txt_xpath = ttk.Button(state3, text="Xpath", width=10)
txt_xpath.grid(column=2, row=6, sticky=E)
self.Proxies = BooleanVar() # 代理
proxies = Checkbutton(state3, text="代理 :", variable=self.Proxies, command=self.proxie)
proxies.grid(column=0, row=7, sticky=W)
self.proxies = ttk.Entry(state3, width=20)
self.proxies.insert(0, "如:000.000.000.000:80")
self.proxies.configure(state='readonly')
self.proxies.grid(column=1, row=7, sticky=W, columnspan=2)
self.Auth = BooleanVar() # 账号密码
auth = Checkbutton(state3, text="Auth :", variable=self.Auth, command=self.author)
auth.grid(column=0, row=8, sticky=W)
self.auth = ttk.Entry(state3, width=20) # setPlaceholderText
self.auth.insert(0, "如:username;password")
self.auth.configure(state='readonly')
self.auth.grid(column=1, row=8, sticky=W, columnspan=2)
self.Redirect = BooleanVar()
redirect = Checkbutton(state3, text="是否允许 重定向", variable=self.Redirect) # 重定向
redirect.select()
redirect.grid(column=0, row=9, sticky=W, columnspan=3)
result_data = ttk.LabelFrame(state3, text="展示结果类型")
result_data.grid(column=0, row=10, columnspan=3)
self.result = IntVar()
self.result.set(99)
Radiobutton(result_data, text="Json", variable=self.result, value=1).grid(column=0, row=9, sticky=W)
Radiobutton(result_data, text="Text", variable=self.result, value=2).grid(column=1, row=9, sticky=W)
r = Radiobutton(result_data, text="None", variable=self.result, value=3)
r.select()
r.grid(column=2, row=9, sticky=W)
# 展示结果
# show = ttk.Frame(http_chkout)
# show.grid(column=0, row=2, pady=10, padx=20, sticky=W, columnspan=3)
self.Show = scrolledtext.ScrolledText(states, width=10, height=20, wrap=WORD)
self.Show.grid(column=0, row=1, sticky='WE', columnspan=3, padx=10)
三、Curl 辅助 窗口
def curl_(self, Curl):
# ----------------- curl 测试界面 ------------------ #
curl = ttk.Frame(Curl)
curl.grid(column=0, row=0, pady=10, padx=20, sticky=W)
Label(curl, text="CURL 命令").grid(column=0, row=0)
self.curl_u = scrolledtext.ScrolledText(curl, width=105, height=20, wrap=WORD)
self.curl_u.grid(column=0, row=1)
Label(curl, text="CURL 转换结果").grid(column=0, row=2)
self.curl_result = scrolledtext.ScrolledText(curl, width=105, height=20, wrap=WORD)
self.curl_result.grid(column=0, row=3)
self.curl_u.bind("<Key>", self.curl_stran)
self.curl_u.bind("<Control-Key-v>", self.curl_stran)
四、最后的验证码窗口设计
def YZM(self, Yzm):
org_init = """请选择图片放入"""
pic = ttk.Frame(Yzm)
pic.grid(column=0, row=0, pady=10, padx=20, sticky=W)
self.pic_yzm1 = Label(pic, relief="sunken", text=org_init)
self.pic_yzm1.bind("<Button-1>", self.open_file)
self.pic_yzm1.grid(column=0, row=0)
self.pic_yzm2 = Label(pic, relief="sunken", text=org_init)
self.pic_yzm2.bind("<Button-1>", self.open_file2)
self.pic_yzm2.grid(column=1, row=0)
txt = "========================================================================================"
Label(pic, width=107, height=1, text=txt).grid(column=0, row=1, columnspan=2)
push_button = ttk.Frame(Yzm)
push_button.grid(column=0, row=1, pady=10, padx=20, sticky=W)
# 请求方式列表
self.code_type = ttk.Combobox(push_button, width=10)
self.code_type['values'] = ('字符验证码', '滑块验证码', '汉字验证码', '点选验证码')
self.code_type.grid(column=0, row=0)
self.code_type.current(0) # 设置初始显示值,值为元组['values']的下标
self.code_type.config(state='readonly') # 设为只读模式
Label(push_button, padx=10, text="验证码结果:").grid(column=2, row=0)
Label(push_button, padx=10, text="").grid(column=5, row=0)
ttk.Button(push_button, text="处理验证码", width=10, command=self.ORC).grid(column=6, row=0)
self.old_ddddorc = IntVar()
dc = Checkbutton(push_button, text="老版本模型", variable=self.old_ddddorc)
dc.deselect()
dc.grid(column=7, row=0, sticky=W)
self.code_result = ttk.Entry(push_button, x=10, width=50)
self.code_result.grid(column=4, row=0, sticky='W')
self.Identify_code = scrolledtext.ScrolledText(Yzm, width=105, height=15, wrap=WORD)
self.Identify_code.grid(column=0, row=2)
以上便是 界面的 设计核心代码
功能设计
1、请求 访问的方法 我选择使用的是支持 http1.0
与 http2.0
相互转换的请求方式,选择了 httpx
2、Curl
转换方面 我使用的 是 curl2py
3、 验证码 识别 选择的 是 ddddocr
4、爬虫 数据解析使用的是 parsel
关于本次 程序设计 1.0 版本 只做了 GET 请求的测试 其他的请求方式还没有设计,大家可以根据自己习惯进行设计开发
一、http 请求
def requests(self, method, url, header_user, http_v):
proxies_ = self.proxies_()
auth = self.Auth_result()
verify = self.verify_()
if "http" in url:
if http_v:
client = httpx.Client(http2=True, verify=verify, proxies=proxies_, auth=auth)
else:
client = httpx.Client(verify=verify, proxies=proxies_, auth=auth)
if method == "GET":
res_dic = self.get_requets(client, url, header_user)
if res_dic["stauts"] == 200:
res = res_dic["res"]
html_ = Selector(res.content.decode(encoding=cchardet.detect(res.content)["encoding"]))
show_result = self.radCall()
self.insert_(word="************* result ***************")
if show_result == "text":
if self.Xpath.get():
show_ = "\n".join(html_).xpath("//text()").getall()
self.insert_(word=show_, h=False)
else:
self.insert_(word=html_.get(), h=False)
elif show_result == "json":
try:
json_ = res.json()
self.insert_(word=json_, h=False)
except:
self.insert_(word="数据 格式 获取错误 请到原数据确认格式, 或确认请求参数是否正确!!!")
else:
self.insert_(word="未 选择 正确的展示格式 !!!", h=False)
else:
self.insert_(word="请求错误 ::::》》》》")
elif method == "POST":
self.insert_(word="未开发项目 ::: 》》》》")
else:
self.insert_(word="未检测到 http(https) 地址====================")
self.insert_(word='************* Over !! ***************')
二、CURL 转换
使用 Curl 命令转换为 Python 代码; 可以更加方便的快速开发爬虫代码功能
def curl_stran(self, event):
li_org = """#######################################
# The generated by curl2py.
# author:小小明
#######################################"""
li_s = """# author: Sheild
# Createtime: {}""".format(datetime.datetime.now())
world = self.curl_u.get(1.0, 'end')
self.curl_u.see(END)
if is_Chinese(world) is None:
if ("-h" in world) or ("-H" in world):
try:
value = curlParseTool.curlCmdGenPyScript(world).replace(li_org, li_s)
self.curl_result.delete(1.0, END)
self.curl_result.insert("insert", value)
self.curl_result.see(END)
except:
pass
else:
pass
else:
pass
三、验证码 识别 核心代码
def ORC(self):
if self.pic_org_ is None:
pass
else:
code_type = self.code_type.get()
print(code_type)
if code_type == "字符验证码":
f = self.pic_org_.replace("\\", "/")
code_file = f"""import ddddocr
orc =ddddocr.DdddOcr(%s)
with open('{f}', 'rb') as f:
img_bytes = f.read()
f.close()
result_num = orc.classification(img_bytes)
print(result_num)"""
if self.old_ddddorc.get():
orc = ddddocr.DdddOcr(old=True) # old=True
code_file = code_file % ("old=True",)
else:
orc = ddddocr.DdddOcr()
code_file = code_file % ("",)
with open(self.pic_org_, 'rb') as f:
img_bytes = f.read()
f.close()
result_num = orc.classification(img_bytes)
self.code_result.delete(0, END)
self.code_result.insert("insert", result_num)
self.Identify_code.delete(1.0, END)
self.Identify_code.insert("insert", code_file)
elif code_type == "点选验证码":
det = ddddocr.DdddOcr(det=True)
code_file = f"""import ddddocr
det = ddddocr.DdddOcr(det=True)
with open('{self.pic_org_}', 'rb') as f:
img_bytes = f.read()
f.close()
poses = det.detection(img_bytes)
print(poses)
################# 结果图片的保存查看 #################
from cv2 import cv2
im = cv2.imread(self.pic_org_)
for box in poses:
x1, y1, x2, y2 = box
im = cv2.rectangle(im, (x1, y1), (x2, y2), color=(0, 0, 255), thickness=2)
cv2.imwrite("result.jpg", im)
"""
with open(self.pic_org_, 'rb') as f:
img_bytes = f.read()
f.close()
poses = det.detection(img_bytes)
print(poses)
self.code_result.delete(0, END)
self.code_result.insert("insert", poses)
self.Identify_code.delete(1.0, END)
self.Identify_code.insert("insert", code_file)
im = cv2.imread(self.pic_org_)
for box in poses:
x1, y1, x2, y2 = box
im = cv2.rectangle(im, (x1, y1), (x2, y2), color=(0, 0, 255), thickness=2)
cv2.imwrite("result.jpg", im)
img_gif = Image.open("result.jpg")
photo = ImageTk.PhotoImage(img_gif)
self.pic_yzm2.config(image=photo)
self.pic_yzm2.image = photo
总结
测试效果图
主界面爬虫测试:
Curl 转换 测试:
验证码 测试 效果:
本文仅供 学习交流
如果需要完整代码 可以私信我,或者下面链接下载源码;
完整源代码下载地址:https://download.csdn.net/download/qq_39832685/85026074