如何在Python程序内部与mitmproxy交互并过滤指定URL请求?
解决方案:在Python类结构中集成mitmproxy实现指定URL请求捕获
核心问题分析
你的需求是通过Python类层级直接与mitmproxy交互,过滤指定URL的请求并减少无关输出。现有方案的问题在于没有利用mitmproxy官方的Addon事件机制来实现请求拦截,而是尝试通过自定义方法直接调用,同时日志控制未完全生效。
步骤1:重构ProxyManager,支持自定义Addon
修改mitmproxystartstop.py,让代理启动时可以加载自定义拦截逻辑,并配置日志级别减少无关输出:
from mitmproxy import options from mitmproxy.tools.dump import DumpMaster import logging class ProxyManager: def __init__(self): self.master = None # 全局设置日志级别为ERROR,屏蔽mitmproxy默认调试输出 logging.basicConfig(level=logging.ERROR) mitm_logger = logging.getLogger("mitmproxy") mitm_logger.setLevel(logging.ERROR) def start_proxy(self, addons=None): # 配置代理监听地址和端口 opts = options.Options(listen_host='0.0.0.0', listen_port=8080) self.master = DumpMaster(opts) # 添加自定义Addon if addons: if isinstance(addons, list): for addon in addons: self.master.addons.add(addon) else: self.master.addons.add(addons) # 后台线程启动代理,避免阻塞主程序 import threading threading.Thread(target=self.master.run, daemon=True).start() def shutdown(self): if self.master: self.master.shutdown()
步骤2:实现URL过滤Addon
创建自定义Addon类,通过mitmproxy的request事件钩子拦截并匹配目标URL:
from mitmproxy import http class RequestFilterAddon: def __init__(self, target_url): # 统一URL格式,移除末尾斜杠避免匹配问题 self.target_url = target_url.rstrip('/') def request(self, flow: http.HTTPFlow) -> None: request_url = flow.request.url.rstrip('/') # 匹配目标URL(支持前缀匹配,比如捕获目标域名下所有请求) if request_url == self.target_url or request_url.startswith(f"{self.target_url}/"): # 输出你需要的请求信息 print(f"[捕获目标请求]") print(f"方法: {flow.request.method}") print(f"URL: {flow.request.url}") # 按需添加请求体、 headers 等信息 # if flow.request.content: # print(f"请求体: {flow.request.content.decode('utf-8', errors='ignore')}") # 非目标URL直接忽略,不输出任何内容
步骤3:调整类层级结构
修改classa_setup_proxy.py,让父类支持传入自定义Addon:
import abc from mitmproxystartstop import ProxyManager class A(abc.ABC): def __init__(self, proxy_addons=None): self.proxy = ProxyManager() self.proxy.start_proxy(addons=proxy_addons) def shutdown_proxy(self): if self.proxy.master: self.proxy.master.shutdown()
修改classb_intercept_a_request.py,继承父类并传入过滤Addon:
import logging from classa_setup_proxy import A from mitmproxy import http class RequestFilterAddon: def __init__(self, target_url): self.target_url = target_url.rstrip('/') def request(self, flow: http.HTTPFlow) -> None: request_url = flow.request.url.rstrip('/') if request_url == self.target_url or request_url.startswith(f"{self.target_url}/"): print(f"[捕获目标请求]") print(f"方法: {flow.request.method}") print(f"URL: {flow.request.url}") class B(A): def __init__(self, target_url): self.filter_addon = RequestFilterAddon(target_url) super().__init__(proxy_addons=self.filter_addon) logging.info("代理已启动,开始监听目标URL请求") def work(self): # 无需循环调用,mitmproxy事件循环在后台运行,这里可添加业务逻辑 pass
步骤4:修改测试代码
调整t_e_s_t_mitmproxyclassb.py,避免重复创建代理实例:
from classb_intercept_a_request import B try: # 指定要捕获的目标URL proxy_program = B(target_url="https://www.google.com/") print("代理运行中,按Ctrl+C停止") # 保持程序运行,等待用户中断 while True: pass except KeyboardInterrupt: print("正在停止代理...") proxy_program.shutdown_proxy() except Exception as e: print(f"错误信息: {e}") if 'proxy_program' in locals(): proxy_program.shutdown_proxy()
关键注意事项
- URL匹配逻辑:可根据需求修改
RequestFilterAddon中的匹配规则,比如使用正则表达式匹配复杂URL模式。 - 代理配置:确保Firefox的代理设置指向mitmproxy的监听地址(默认
127.0.0.1:8080)。 - 日志控制:通过设置mitmproxy专属日志器级别,彻底屏蔽无关调试输出。
内容的提问来源于stack exchange,提问作者user28215801
相关产品推荐
相关产品推荐

