用Mitmproxy搭建个人数据抓取代理服务器

在网络爬虫和数据采集领域,传统的 HTTP 请求库(如 requests、aiohttp)往往面临着复杂的反爬机制挑战:动态加载内容、JS 加密、Cookie 验证、API 签名等。而 Mitmproxy 作为一款强大的中间人代理工具,能够直接拦截和修改客户端与服务器之间的所有 HTTP/HTTPS 流量,为数据抓取提供了一种全新的思路和解决方案。

本文将带你从零开始,一步步搭建属于自己的 Mitmproxy 数据抓取代理服务器,从基础安装配置到高级 Python 脚本自动化,全面掌握这一 "网络中间人" 利器。

一、Mitmproxy 简介

Mitmproxy 是一个开源的、交互式的 HTTPS 代理工具,由 Python 编写而成。它不仅可以像 Fiddler、Charles 那样查看和分析网络流量,更重要的是它提供了强大的脚本扩展能力,让你能够用 Python 代码全自动地处理、过滤和存储网络数据。

1.1 三大核心组件

Mitmproxy 安装后会提供三个独立的命令行工具:

  • mitmproxy:基于终端的交互式界面,支持实时查看、过滤和修改流量(Windows 系统不支持)
  • mitmdump:命令行版本的 mitmproxy,适合后台运行和脚本自动化
  • mitmweb:基于 Web 的图形界面,操作直观,强烈推荐新手使用

1.2 Mitmproxy 的优势

  • 跨平台:完美支持 Windows、macOS 和 Linux 系统
  • HTTPS 支持:能够完整解密和查看 HTTPS 流量
  • 脚本化:通过 Python 钩子函数实现全自动流量处理
  • 可扩展:丰富的插件生态和 API 接口
  • 免费开源:完全免费且代码开源,无功能限制

二、环境准备与安装

2.1 系统要求

  • Python 版本:3.12 及以上(Mitmproxy 12.x 要求)
  • 操作系统:Windows 10+/macOS 10.15+/Linux
  • 网络环境:确保电脑和目标设备在同一局域网内

2.2 安装方法

方法一:官方安装包(推荐)

前往Mitmproxy 官方网站下载对应系统的安装包,直接运行安装即可。安装完成后,三个工具会自动添加到系统 PATH 中。

方法二:使用包管理器

macOS(Homebrew)

bash

运行

复制代码
brew install --cask mitmproxy

Linux

bash

运行

复制代码
# Ubuntu/Debian
sudo apt install mitmproxy

# Arch Linux
sudo pacman -S mitmproxy
方法三:通过 Python pip 安装

bash

运行

复制代码
# 先确保pip是最新版本
pip install --upgrade pip

# 安装mitmproxy
pip install mitmproxy

2.3 验证安装

打开终端或命令提示符,输入以下命令验证安装是否成功:

bash

运行

复制代码
mitmdump --version

如果看到类似以下输出,说明安装成功:

plaintext

复制代码
Mitmproxy: 12.0.0
Python:    3.12.3
OpenSSL:   OpenSSL 3.2.1 30 Jan 2024
Platform:  Windows-10-10.0.22631-SP0

三、基础代理配置

3.1 启动代理服务器

最简单的启动方式是直接运行 mitmweb(推荐新手使用):

bash

运行

复制代码
mitmweb

启动成功后,终端会显示类似信息:

plaintext

复制代码
Web server listening at http://127.0.0.1:8081/
Proxy server listening at http://*:8080

如果你想指定其他端口,可以使用-p参数:

bash

运行

复制代码
mitmweb -p 8888

3.2 配置客户端代理

要让设备的流量经过 Mitmproxy,需要在客户端设备上配置代理服务器。

电脑端配置

Windows 系统

  1. 打开 "设置" → "网络和 Internet" → "代理"
  2. 开启 "使用代理服务器"
  3. 地址:输入运行 Mitmproxy 的电脑的局域网 IP 地址
  4. 端口:8080(或你指定的端口)
  5. 点击 "保存"

macOS 系统

  1. 打开 "系统设置" → "网络"
  2. 选择当前连接的 Wi-Fi,点击 "详细信息"
  3. 切换到 "代理" 选项卡
  4. 勾选 "网页代理 (HTTP)" 和 "安全网页代理 (HTTPS)"
  5. 输入服务器地址和端口 8080
  6. 点击 "好"
手机端配置

Android 系统

  1. 打开 "设置" → "WLAN"
  2. 长按当前连接的 Wi-Fi 名称,选择 "修改网络"
  3. 勾选 "显示高级选项"
  4. 代理设置:选择 "手动"
  5. 服务器主机名:输入电脑的局域网 IP
  6. 服务器端口:8080
  7. 点击 "保存"

iOS 系统

  1. 打开 "设置" → "无线局域网"
  2. 点击当前连接的 Wi-Fi 右侧的 "i" 图标
  3. 滚动到 "HTTP 代理" 部分,选择 "手动"
  4. 服务器:输入电脑的局域网 IP
  5. 端口:8080
  6. 点击 "存储"

四、HTTPS 证书配置(关键步骤)

这是整个配置过程中最关键的一步。现代互联网几乎全部使用 HTTPS 加密传输,如果不安装 Mitmproxy 的 CA 证书,你将只能看到加密的乱码数据,无法解密和查看 HTTPS 请求的具体内容。

4.1 证书生成

首次运行 Mitmproxy 时,它会自动在用户目录下生成一个.mitmproxy文件夹,里面包含了所有需要的证书文件:

  • mitmproxy-ca-cert.pem:适用于 Linux、macOS 和大多数移动设备
  • mitmproxy-ca.p12:适用于 Windows 系统
  • mitmproxy-ca-cert.cer:适用于部分 Android 设备

4.2 电脑端证书安装

Windows 系统

  1. 确保 Mitmproxy 正在运行
  2. 打开浏览器访问:http://mitm.it/
  3. 点击 "Windows" 图标下载证书
  4. 双击下载的mitmproxy-ca-cert.p12文件
  5. 存储位置选择 "当前用户",点击 "下一步"
  6. 密码留空,直接点击 "下一步"
  7. 选择 "将所有的证书都放入下列存储",点击 "浏览"
  8. 选择 "受信任的根证书颁发机构",点击 "确定"
  9. 点击 "下一步" → "完成"

macOS 系统

  1. 访问http://mitm.it/下载 macOS 证书
  2. 双击下载的mitmproxy-ca-cert.pem文件
  3. 在钥匙串访问中找到 "mitmproxy" 证书
  4. 双击证书,展开 "信任" 部分
  5. 将 "使用此证书时" 改为 "始终信任"
  6. 关闭窗口,输入系统密码确认更改

4.3 手机端证书安装

Android 系统

  1. 确保手机已经配置好代理
  2. 打开手机浏览器访问:http://mitm.it/
  3. 点击 "Android" 图标下载证书
  4. 下载完成后,系统会提示安装证书
  5. 证书用途选择 "VPN 和应用"
  6. 输入证书名称(如 "mitmproxy"),点击 "确定"

iOS 系统

  1. 确保手机已经配置好代理
  2. 打开 Safari 浏览器访问:http://mitm.it/
  3. 点击 "iOS" 图标下载证书描述文件
  4. 系统会提示 "已下载描述文件",点击 "关闭"
  5. 打开 "设置" → "通用" → "VPN 与设备管理"
  6. 在 "已下载的描述文件" 下点击 "mitmproxy"
  7. 点击右上角的 "安装",输入锁屏密码
  8. 再次点击 "安装" → "安装"
  9. 关键步骤:打开 "设置" → "通用" → "关于本机" → "证书信任设置"
  10. 开启 "mitmproxy" 证书的完全信任开关
  11. 点击 "继续" 确认

五、基础使用入门

5.1 mitmweb 界面介绍

打开浏览器访问http://127.0.0.1:8081/,你会看到 mitmweb 的主界面:

  • 左侧列表:显示所有捕获的 HTTP/HTTPS 请求
  • 右侧详情 :分为 Request 和 Response 两个标签页
    • Request:显示请求方法、URL、请求头、请求体等信息
    • Response:显示响应状态码、响应头、响应体等信息
  • 顶部工具栏:提供搜索、过滤、清空、保存等功能

5.2 过滤流量

mitmweb 支持强大的过滤语法,可以快速找到你需要的请求:

  • 按域名过滤:~d example.com
  • 按请求方法过滤:~m POST
  • 按响应状态码过滤:~s 200
  • 按 URL 关键词过滤:~u api
  • 组合过滤:~d example.com ~m POST ~u api

5.3 保存和导出数据

你可以将捕获的流量保存为文件,以便后续分析:

  1. 选中要保存的请求
  2. 点击右上角的 "Export" 按钮
  3. 选择导出格式(HAR、curl 命令、Python 代码等)
  4. 保存到本地文件

六、高级用法:Python 脚本自动化数据抓取

这是 Mitmproxy 最强大的功能。通过编写 Python 脚本,你可以实现全自动的数据抓取、过滤、清洗和存储,完全摆脱手动操作的繁琐。

6.1 脚本基础

Mitmproxy 脚本基于事件钩子机制工作。你只需要定义特定的函数,当对应的事件发生时,Mitmproxy 会自动调用这些函数。

最常用的两个事件钩子:

  • request(flow):在客户端请求到达 Mitmproxy 后,转发给服务器之前触发
  • response(flow):在服务器响应到达 Mitmproxy 后,返回给客户端之前触发

6.2 示例 1:简单的数据抓取脚本

这个脚本会自动捕获所有包含 "api/articles" 的请求,并将文章数据保存到 JSON 文件中:

python

运行

复制代码
# save as article_spider.py
import json
from mitmproxy import http

# 存储捕获的数据
captured_articles = []

def response(flow: http.HTTPFlow):
    """处理服务器响应"""
    # 只处理目标API请求
    if "api/articles" in flow.request.url and flow.response.status_code == 200:
        try:
            # 解析JSON响应
            response_data = json.loads(flow.response.text)
            
            # 提取需要的字段
            articles = response_data.get("data", [])
            for article in articles:
                article_info = {
                    "id": article.get("id"),
                    "title": article.get("title"),
                    "author": article.get("author", {}).get("name"),
                    "views": article.get("views"),
                    "publish_time": article.get("created_at")
                }
                captured_articles.append(article_info)
            
            print(f"✅ 成功捕获 {len(articles)} 条文章数据,总计 {len(captured_articles)} 条")
            
            # 实时保存到文件
            with open("articles.json", "w", encoding="utf-8") as f:
                json.dump(captured_articles, f, ensure_ascii=False, indent=2)
                
        except json.JSONDecodeError:
            print(f"❌ JSON解析失败: {flow.request.url}")
        except Exception as e:
            print(f"❌ 处理请求出错: {e}")

运行脚本:

bash

运行

复制代码
mitmdump -s article_spider.py

6.3 示例 2:修改请求参数突破接口限制

很多 App 和网站的 API 会限制单页返回的数据量,通过 Mitmproxy 可以轻松修改请求参数:

python

运行

复制代码
# save as modify_params.py
from mitmproxy import http

def request(flow: http.HTTPFlow):
    """修改请求参数"""
    if "api/list" in flow.request.url:
        # 将单页返回条数从10改为100
        flow.request.query["page_size"] = "100"
        # 修改页码
        flow.request.query["page"] = "1"
        print(f"✅ 修改请求参数: {flow.request.url}")

6.4 示例 3:自动保存图片

这个脚本会自动将所有捕获的图片保存到本地文件夹:

python

运行

复制代码
# save as save_images.py
import os
from mitmproxy import http

# 创建保存图片的文件夹
os.makedirs("captured_images", exist_ok=True)

def response(flow: http.HTTPFlow):
    """保存图片响应"""
    content_type = flow.response.headers.get("content-type", "")
    
    # 只处理图片类型
    if content_type.startswith("image/"):
        # 获取文件扩展名
        ext = content_type.split("/")[-1]
        if ext == "jpeg":
            ext = "jpg"
            
        # 生成文件名
        filename = f"{flow.request.host}_{flow.request.path.split('/')[-1]}.{ext}"
        filepath = os.path.join("captured_images", filename)
        
        # 保存图片
        with open(filepath, "wb") as f:
            f.write(flow.response.content)
            
        print(f"✅ 保存图片: {filename}")

七、常见问题排查

7.1 HTTPS 抓包失败

症状:浏览器显示 "您的连接不是私密连接",App 无法联网,mitmproxy 中看到 SSL 错误。

解决方案

  1. 确认证书已正确安装并受信任
  2. iOS 用户务必检查 "证书信任设置" 是否开启
  3. Android 7 + 系统中,用户证书默认不被应用信任,需要将证书安装为系统证书(需要 root 权限)
  4. 清除浏览器缓存和 HSTS 记录

7.2 代理配置后无流量

症状:mitmproxy 界面中没有显示任何请求。

解决方案

  1. 确认客户端和服务器在同一局域网内
  2. 检查电脑防火墙是否阻止了 8080 端口
  3. 确认代理地址和端口配置正确
  4. 尝试重启 Mitmproxy 和客户端设备

7.3 部分 App 无法抓包

症状:大多数 App 可以正常抓包,但某些特定 App 无法联网或看不到请求。

原因:这些 App 启用了 ** 证书绑定(Certificate Pinning)** 技术,它们会直接校验服务器证书的指纹,而不信任系统安装的 CA 证书。

解决方案

  1. 对于 Android 设备,可以使用 Frida、Xposed 等工具绕过证书绑定
  2. 对于 iOS 设备,可以使用 SSL Kill Switch 2 等插件
  3. 注意:绕过证书绑定可能违反应用的服务条款,请谨慎使用

八、安全注意事项

  1. 合法使用:仅对你拥有或有权限测试的网站和应用进行抓包,未经授权的抓包行为可能违反法律法规
  2. 证书安全:不要将你的 Mitmproxy CA 证书分享给他人,否则可能导致中间人攻击
  3. 数据安全:抓取到的数据可能包含敏感信息(如密码、Token),请妥善保管
  4. 关闭代理:使用完毕后及时关闭客户端代理,避免影响正常上网

九、总结

Mitmproxy 作为一款强大的中间人代理工具,为数据抓取提供了一种高效、灵活的解决方案。它不仅能够轻松绕过大多数前端反爬机制,还能通过 Python 脚本实现全自动的数据处理流程。

通过本文的学习,你应该已经掌握了:

  • Mitmproxy 的安装和基础配置
  • HTTPS 证书的安装和信任设置
  • mitmweb 界面的基本使用
  • Python 脚本自动化数据抓取的方法
  • 常见问题的排查和解决

当然,Mitmproxy 的功能远不止于此。你还可以探索更多高级用法,如请求重定向、响应修改、Mock 测试、透明代理等。希望这篇文章能帮助你开启 Mitmproxy 数据抓取的大门,让你的爬虫工作更加高效和轻松。