mitmproxy_录制接口并保存到mysql(踩坑史)

一、踩的坑
1、首选这个脚本获取请求信息方式,与上个文章,写入csv一致
2、坑主要是在插入数据库中
(1)mitmproxy获取到的url等信息,虽然是字符串,但是两边没有双引号,强制
str()都不行,插入数据库还报错,因此只能手动加

each_result = "\""+str(each_result)+"\""

(2) 如果返回的response是个json串,他里面的元素是有双引号的,插入数据库也会报错,应当转义成单引号

 each_result = each_result.replace("\"","'")

二、直接上代码吧
1、首先,先创建个mysql数据库,把表创建好

image.png

image.png

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()
]

三、结果就是这个样子

image.png

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将上传的PDF文件路径保存MySQL数据库,你需要使用Flask提供的SQLAlchemy库。具体步骤如下: 1. 在Flask应用程序中,创建一个模型类来表示PDF文件。在这个模型类中,定义一个名为 pdf_path 的属性来保存PDF文件的路径,例如: ```python from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class PDFFile(db.Model): id = db.Column(db.Integer, primary_key=True) pdf_path = db.Column(db.String(255)) ``` 在上面的代码中,我们使用 SQLAlchemy 定义了一个名为 PDFFile 的模型类,其中包含了一个名为 pdf_path 的属性,用于保存PDF文件的路径。 2. 在Flask应用程序中,创建一个路由函数来处理上传的PDF文件,并将其保存MySQL数据库中。在这个函数中,首先使用 request 对象获取上传的文件,并保存到服务器上的一个临时目录中。然后,创建一个 PDFFile 对象,并将 PDF 文件的路径保存到 pdf_path 属性中。最后,将 PDFFile 对象保存MySQL 数据库中,例如: ```python from flask import Flask, request app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://user:password@localhost/db_name' db.init_app(app) @app.route('/upload', methods=['POST']) def upload(): pdf_file = request.files['pdf_file'] pdf_path = '/tmp/' + pdf_file.filename pdf_file.save(pdf_path) pdf = PDFFile(pdf_path=pdf_path) db.session.add(pdf) db.session.commit() return 'File uploaded!' ``` 在上面的代码中,我们首先使用 app.config 来配置 MySQL 数据库连接信息。然后,使用 db.init_app() 方法初始化 SQLAlchemy。在 upload() 函数中,我们首先获取上传的 PDF 文件,并保存到服务器上的一个临时目录中。然后,创建一个 PDFFile 对象,将 PDF 文件的路径保存到 pdf_path 属性中。最后,使用 db.session.add() 方法将 PDFFile 对象添加到数据库中,并使用 db.session.commit() 方法提交更改。 3. 现在你已经将上传的 PDF 文件保存到了 MySQL 数据库中。要获取 PDF 文件的路径,只需要查询数据库中的 PDFFile 对象,并使用 pdf_path 属性获取路径,例如: ```python pdf = PDFFile.query.filter_by(id=1).first() pdf_path = pdf.pdf_path ``` 在上面的代码中,我们使用 PDFFile.query.filter_by() 方法查询数据库中的 PDFFile 对象,并使用 first() 方法获取第一个匹配的对象。然后,使用 pdf.pdf_path 属性获取 PDF 文件的路径。 注意:在实际应用中,你需要根据你的需求修改上面的代码,例如将临时目录改为你自己的目录,并添加文件名的校验等。同时,你还需要在 MySQL 数据库中创建一个名为 PDFFile 的表,用于保存 PDF 文件的路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值