一、实现思路:
(1)首先抓取到自己需要的信息,比如说请求头,请求地址,请求方法,响应信息等等
(2)存到哪个地方,全看自己需要,要么存到一个数据库里,要么存放到csv文件里
(3)因为mitmproxy会抓取很多http请求,有的可能不是你想要的,所以为了抓到你想要的,你需要对http的ip地址过滤
(4)抓取头文件,头文件的返回值元组型的数据,但是我们如果后面做接口回放,需要request请求,request请求头文件是字典格式,所以我们要把读取到的头文件进行转写
(5)在录制的时候,有可能不只录制一次,为了保存每次录制的文件都是唯一的,并且知道我们录制的文件是哪一个。我们可以选择用时间当文件信息
(6)每个用例,都有用例编号,所以我们还要生成用例id,一般是000001,000011这类的
那下来我们就来看看具体的代码实现,我们写两种方式,一种是写到csv,一种是写入数据库,其实读取代码的方式都一样,主要是就存储的代码方式不一样
二、使用csv文件来存接口结果
现在我们来做一些写代码前的准备
1、可以创建一个config文件,里面存放一些配置信息,这里我们可以创建一个ip列表,里面存放我们需要抓取的ip地址,将不需要的地址过滤掉
我们可以创建一个config文件,里面写一些配置信息
host = ["127.0.0.1"] #要收集的ip地址
#设置一个csv表头也可以将来做为数据库字段名
headline = ["ID","url","request_method","request_head","body","reponse_status","response_text"]
2、写一个时间函数,用来当成csv文件的名子
import time
class CsvUtils:
@staticmethod
def generate_name_current_time():
name = time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime())
return name
3、写一个函数,实现向csv文件里面写数据
def write_csv_by_add(csv_path, text):
'''
:param csv_path: 文件路径
:param text: 要写入的信息,必须是列表
:return:
'''
try:
if text not in [None, ""]:
if isinstance(text, list):
with open(csv_path, "a+", encoding="utf-8") as w:
csv_writer = csv.writer(w)
csv_writer.writerow(text)
else:
print("写入的text,不是列表格式")
else:
print("写入的text,不能为空")
except:
print(("写csv文件时发生未知异常"))
4、现在进入正题,开始读取录制的脚本
# -*-coding:utf-8-*-
from config import hosts, headline
from python_utils.csv.csv_utils import CsvUtils
from python_utils.csv.csv_writer import CSVWriter
from mitmproxy import ctx
import json
class ApiRecordHelper:
def __init__(self):
# 刚才写的获取当前时间的工具,我们要习惯如果这个代码块常用我们就要把他写成一个工具类,方便日后调用
self.result = []
self.count = 1
self.result_name = CsvUtils.generate_name_current_time()
self.result_path = "./doc/record_%s.csv" % self.result_name
CSVWriter.write_csv_by_add(self.result_path, headline)
def request(self, flow): # flow是固定参数,可以理解成存着全部的request和response信息
info = ctx.log.info # 可以在mitmproxy录制的内容中,打印出自己的信息,这个可以用来做调试
request = flow.request # 这里没有代码联想,所以别写错了
url = request.url
for host in hosts:
if host in url: # 只收集我想要的ip地址相关的接口
info("得到的未过滤的url"+url)
new_headers = {}
body_type = None
body = None
ID = '{:0>5d}'.format(self.count) # 生成用例id
request_method = request.method
headers = request.headers
for key, value in headers.items(): # 生成字典样式的header
new_headers[key] = value
if "Content-Type" in new_headers.keys():
body_type = new_headers["Content-Type"]
if request.get_text():
body = request.get_text()
self.result = [ID, url, request_method, str(new_headers), str(body_type), str(body)]
def response(self, flow):
info = ctx.log.info
response = flow.response
url = flow.request.url # 获取这个响应是来自哪个url
response_status = None
response_text = None
if len(self.result) > 0 and url == self.result[1]: # 只有响应是来自上个自己想要的url,我才要
if response.status_code:
response_status = str(response.status_code)
if response.text:
try:
json.loads(response.text)
response_text = response.text.encode('utf-8').decode('unicode_escape') #这个要转码,否则中文会显示乱码
except:
response_text = response.text
self.result.append(response_status)
self.result.append(response_text)
CSVWriter.write_csv_by_add(self.result_path, self.result)
self.count = self.count+1
self.result = []
addons = [
ApiRecordHelper()
]
最后输出的结果
image.png