一、踩的坑
1、首选这个脚本获取请求信息方式,与上个文章,写入csv一致
2、坑主要是在插入数据库中
(1)mitmproxy获取到的url等信息,虽然是字符串,但是两边没有双引号,强制
str()都不行,插入数据库还报错,因此只能手动加
each_result = "\""+str(each_result)+"\""
(2) 如果返回的response是个json串,他里面的元素是有双引号的,插入数据库也会报错,应当转义成单引号
each_result = each_result.replace("\"","'")
二、直接上代码吧
1、首先,先创建个mysql数据库,把表创建好
2、写一个数据库的工具函数吧,方便反复调用,这个网上一搜一大把
import pymysql
class MysqlUtils:
@staticmethod
def execute_sql(host, port, user, password, db_name, sql_sentence):
db_config = [host,port,user,password,db_name]
for each_config in db_config:
if each_config in [None,""]:
print("数据库配置host,port ,user,password,db_name缺失")
return
connect = pymysql.Connect(
host=host,
port=port,
user=user,
passwd=password,
db=db_name,
charset='utf8'
)
cursor = connect.cursor()
try:
cursor.execute(sql_sentence)
connect.commit()
cursor.close()
connect.close()
except Exception as e:
print("执行数据库命令出错")
print(str(e))
3、正戏代码开始了,里面写了注释,自己参考吧
# -*-coding:utf-8-*-
from config.config import hosts, db_all_api, db_config
from mitmproxy import ctx
import json
from python_utils.csv.csv_utils import CsvUtils
from python_utils.db.mysql_utils import MysqlUtils
class ApiRecordHelperToDB:
def __init__(self):
# 刚才写的获取当前时间的工具,我们要习惯如果这个代码块常用我们就要把他写成一个工具类,方便日后调用
self.result = []
self.create_time = CsvUtils.generate_name_current_time(format="%Y%m%d%H%M%S")
self.count = 1
self.all_result = []
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, self.create_time, 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
format_result = []
response_status = None
response_text = None
if len(self.result) > 0 and url == self.result[2]: # 只有响应是来自上个自己想要的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:
if "</html>" in response.text:
response_text = "html网页"
else:
response_text = response.text
self.result.append(response_status)
self.result.append(response_text)
new_db_config = list(db_config)
new_result = []
for each_result in self.result:
# 坑一,从mtimproxy爬下来的内容虽然是字符串,但是两边没有双引号,插入数据会报错,因此得手动加双引号
each_result = each_result.replace("\"","'")
# 坑二,如果返回是json串,是双引号,但插入数据库的时候,会跟前面的双引号重复,因此需要转义成单引号
each_result = "\""+str(each_result)+"\""
new_result.append(each_result)
data = ",".join(new_result)
#坑三,这个方一定要写上数据库的字段,否则前面你数据库自增的索引id也会让你添加
cmd = '''insert into %s (case_id, create_time, url, request_method, headers, body_type, body,response_status,response_text) values (%s)''' % (db_all_api,data)
info("---------cmd-----------"+cmd)
MysqlUtils.execute_sql(new_db_config[0], new_db_config[1], new_db_config[2], new_db_config[3],
new_db_config[4], cmd)
self.count = self.count + 1
addons = [
ApiRecordHelperToDB()
]
三、结果就是这个样子