基于 mitmproxy 的大众点评数据采集实战:自动化抓取景点与评论数据

基于 mitmproxy 的大众点评数据采集实战:自动化抓取景点与评论数据

📚 前言

在数据分析和市场研究中,爬取大众点评等平台的数据是常见需求。然而,传统的爬虫方式在面对小程序、APP 等场景时往往力不从心。本文将介绍一种基于 mitmproxy 的数据采集方案,通过 HTTP 代理拦截的方式,实现对大众点评小程序数据的自动化采集。

🎯 技术方案概述

为什么选择 mitmproxy?

  1. 小程序/APP 数据采集:小程序和 APP 的网络请求无法直接访问,需要通过代理拦截
  2. 真实请求拦截:mitmproxy 可以拦截真实的 HTTP/HTTPS 请求,获取原始 API 数据
  3. 避免反爬虫:使用真实的客户端请求,降低被反爬虫检测的风险
  4. 数据处理灵活:可以在拦截层直接解析和处理数据

核心架构

复制代码
PC微信(大众点评小程序) 
    ↓ HTTP请求
mitmproxy代理服务 (拦截/解析)
    ↓ 处理后的数据
MySQL数据库 / CSV文件

🛠️ 环境搭建

1. 安装 Python 环境

项目基于 Python 3.12,推荐使用 uv 进行依赖管理:

bash 复制代码
# 安装 uv (可选)
pip install uv

# 安装项目依赖
uv pip install -r requirements.txt
# 或
pip install -r requirements.txt

2. 核心依赖说明

python 复制代码
mitmproxy==11.0.2      # HTTP代理工具
pyautogui==0.9.54      # GUI自动化(模拟滚动)
pymysql==1.1.1         # MySQL数据库操作
python-dotenv==1.1.1   # 环境变量管理

3. 数据库配置(可选)

创建 .env 文件配置数据库:

env 复制代码
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_password
DB_NAME=dianping_spiders
DB_CHARSET=utf8mb4

💻 核心代码实现

1. 主程序架构 (main.py)

主程序负责整体流程控制,包括代理管理、服务启动和滚动控制。

1.1 代理管理器
python 复制代码
class ProxyManager:
    """代理管理器,负责设置和恢复系统代理"""
    
    def __init__(self, proxy_host: str = "127.0.0.1", proxy_port: int = 8080):
        self.proxy_host = proxy_host
        self.proxy_port = proxy_port
        self.system = platform.system().lower()
        self.original_settings = {}
    
    def set_proxy(self) -> bool:
        """设置系统代理"""
        if self.system == "darwin":  # macOS
            return self._set_macos_proxy()
        elif self.system == "windows":  # Windows
            return self._set_windows_proxy()

关键点

  • 支持 Windows 和 macOS 双平台
  • 自动保存原始代理设置,退出时恢复
  • Windows 通过注册表设置,macOS 通过命令行工具设置
1.2 mitmweb 服务管理
python 复制代码
class MitmWebManager:
    """mitmweb服务管理器"""
    
    def start(self) -> bool:
        """启动mitmweb服务"""
        cmd = [
            "mitmweb",
            "-s", self.script_path,      # 加载拦截脚本
            "--listen-port", str(self.port),    # 代理端口
            "--web-port", str(self.port + 1)    # Web界面端口
        ]
        self.process = subprocess.Popen(cmd, ...)

特性

  • 自动检测服务状态
  • 异常退出时自动重启(最多3次)
  • 日志记录和错误追踪
1.3 滚动控制
python 复制代码
def scroll(scroll_count: int = 99999, 
           scroll_pause: float = 1, 
           speed: int = -200) -> None:
    """模拟下滑操作"""
    for i in range(scroll_count):
        pyautogui.scroll(speed)  # 向下滚动
        time.sleep(scroll_pause)  # 等待数据加载

交互控制

  • 空格键:暂停/继续
  • ESC 键:退出程序

2. 评论数据拦截 (src/pinglun_list.py)

这是项目的核心数据采集模块,实现评论 API 的拦截和解析。

2.1 响应拦截函数
python 复制代码
def response(flow: http.HTTPFlow) -> None:
    """处理HTTP响应,拦截大众点评评论数据"""
    # 检查是否是目标URL
    if TARGET_URL_PATTERN not in flow.request.url:
        return
    
    # 验证响应状态
    if flow.response.status_code != 200:
        return
    
    # 解析JSON响应
    response_json = flow.response.json()
    
    # 获取请求参数
    shop_uuid = flow.request.query.get('shopId')
    offset = flow.request.query.get('offset')
    
    # 保存原始响应和解析数据
    _save_response_file(flow, shop_uuid, offset)
    parse_json(response_json, shop_uuid, offset)
2.2 数据解析和存储
python 复制代码
def parse_json(response_data: Dict[str, Any], 
               shop_uuid: str, 
               offset: str) -> None:
    """解析JSON数据并保存到CSV文件"""
    review_list = response_data['reviewInfo']['reviewListInfo']['reviewList']
    
    # 为每个shop_uuid创建单独的CSV文件
    csv_file_path = CSV_DIR / f"{shop_uuid}.csv"
    
    with open(csv_file_path, 'a+', newline='', encoding='utf-8-sig') as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        
        if not csv_file_path.exists():
            writer.writeheader()  # 写入表头
        
        # 写入每条评论
        for review in review_list:
            writer.writerow({
                'reviewId': review.get('reviewId'),
                'shopUuid': shop_uuid,
                'userId': review.get('userId'),
                'text': _extract_review_text(review),
                'pics': _extract_review_pics(review),
                # ... 其他字段
            })

数据存储策略

  • CSV 文件:每个店铺一个文件,支持追加模式
  • 原始 JSON :保存到 log/dianping_responses/ 用于回溯
  • UTF-8 with BOM:确保 Excel 正确打开中文

3. 景点数据拦截 (src/jingdian_list.py)

景点数据的拦截和存储逻辑与评论类似,但保存到 MySQL 数据库。

3.1 数据库插入逻辑
python 复制代码
sql = """
    INSERT INTO attractions (
        shopUuid, categoryName, name, defaultPic, priceText, 
        recommendReason, regionName, reviewCount, starScore, ...
    ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, ...)
    ON DUPLICATE KEY UPDATE
        categoryName = VALUES(categoryName),
        name = VALUES(name),
        ...
        updated_at = CURRENT_TIMESTAMP
"""

关键特性

  • 使用 ON DUPLICATE KEY UPDATE 避免重复数据
  • 自动更新时间戳
  • 参数化查询防止 SQL 注入

4. 数据库封装 (src/mysql.py)

采用单例模式管理数据库连接:

python 复制代码
class MySQLDatabase:
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(MySQLDatabase, cls).__new__(cls)
            cls._instance.__connect()
        return cls._instance
    
    def __connect(self):
        """连接到MySQL数据库"""
        db_config = DatabaseConfig.get_mysql_config()
        self.connection = pymysql.connect(**db_config)
        self.cursor = self.connection.cursor(cursor=cursors.DictCursor)

🚀 使用流程

步骤 1:启动程序

bash 复制代码
python main.py

程序会自动:

  1. 启动 mitmweb 服务(端口 8080)
  2. 设置系统代理
  3. 显示 3 秒倒计时

步骤 2:打开目标页面

在 PC 微信中打开大众点评小程序,进入:

  • 景点列表页:采集景点信息
  • 评论列表页:采集评论数据

步骤 3:自动采集

程序开始自动滚动页面,触发数据加载:

  • 每次滚动后等待 3-5 秒(随机)
  • mitmproxy 自动拦截 API 请求
  • 数据自动保存到本地

步骤 4:查看数据

  • 评论数据log/dianping_csv/{shop_uuid}.csv
  • 景点数据 :MySQL 数据库 attractions
  • 原始响应log/dianping_responses/{shop_uuid}/

🔍 技术要点详解

1. mitmproxy 脚本机制

mitmproxy 提供了多个钩子函数,本项目主要使用:

  • request(flow): 请求拦截(可用于修改请求)
  • response(flow): 响应拦截(用于提取数据)
python 复制代码
from mitmproxy import http

def response(flow: http.HTTPFlow) -> None:
    # flow.request: 请求对象
    # flow.response: 响应对象
    response_json = flow.response.json()
    # 处理数据...

2. 代理证书安装

首次使用 mitmproxy 需要安装证书:

  1. 启动 mitmproxy 后,访问 http://mitm.it
  2. 根据操作系统下载证书
  3. 安装到系统信任的根证书存储区

3. 滚动参数优化

滚动参数影响采集效率和稳定性:

python 复制代码
# 快速采集(可能漏数据)
scroll_pause = 1, speed = -2000

# 稳定采集(推荐)
scroll_pause = random.randint(3, 5), speed = random.randint(-2000, -1000)

# 慢速采集(最稳定)
scroll_pause = 5, speed = -500

4. 错误处理和重试

python 复制代码
# mitmweb 服务监控
def _monitor_process(self) -> None:
    while self.should_monitor:
        if self.process.poll() is not None:
            # 服务退出,自动重启
            if self.restart_count < self.max_restarts:
                self._restart_service()

📊 数据采集结果

评论数据示例(CSV)

reviewId shopUuid userId addTime text pics star offset
123456 abc123... user1 1234567890 很不错的景点... url1,url2 5 0
123457 abc123... user2 1234567900 景色优美... url3 4 0

景点数据示例(数据库)

shopUuid name categoryName starScore reviewCount regionName
abc123... 西湖 景点/景区 4.5 1234 杭州

⚠️ 注意事项和最佳实践

1. 合法使用

  • 本工具仅供学习研究使用
  • 遵守网站服务条款和相关法律法规
  • 控制采集频率,避免对服务器造成压力

2. 数据采集建议

  • 分批采集:不要一次性采集大量数据
  • 随机延迟:使用随机延迟模拟人类行为
  • 错误重试:实现合理的重试机制
  • 数据去重:避免重复采集相同数据

3. 性能优化

  • 使用数据库连接池
  • 批量插入数据而非逐条插入
  • 异步处理非关键路径

4. 故障排查

问题 1:无法拦截数据

  • 检查代理是否设置成功
  • 确认 mitmproxy 证书已安装
  • 验证目标 URL 模式是否正确

问题 2:数据解析错误

  • 检查 JSON 结构是否变化
  • 查看原始响应文件进行调试
  • 添加异常处理和日志

🎓 扩展应用

1. 扩展到其他平台

相同的技术方案可以应用于:

  • 美团、饿了么等本地生活平台
  • 淘宝、京东等电商平台
  • 抖音、快手等短视频平台

2. 数据处理和分析

采集到的数据可以用于:

  • 情感分析:分析评论的情感倾向
  • 用户画像:基于评论行为分析用户特征
  • 竞品分析:对比不同商家的评分和评论
  • 市场调研:分析用户偏好和消费趋势

3. 实时监控

可以扩展为实时监控系统:

  • 监控特定店铺的新评论
  • 价格变动提醒
  • 评分变化追踪

📚 总结

本文介绍了基于 mitmproxy 的数据采集方案,通过以下几个关键点实现了高效的数据采集:

  1. 代理拦截:使用 mitmproxy 拦截真实 API 请求
  2. 自动化滚动:pyautogui 模拟用户行为触发数据加载
  3. 数据持久化:CSV 和 MySQL 双重存储方案
  4. 错误处理:完善的异常处理和自动恢复机制

这种方案的优势在于:

  • ✅ 绕过传统爬虫的限制
  • ✅ 获取真实 API 数据,结构清晰
  • ✅ 自动化程度高,减少人工干预
  • ✅ 易于扩展和维护

希望本文对需要采集小程序/APP 数据的开发者有所帮助。如有问题,欢迎交流讨论!


技术交流:欢迎在评论区讨论相关技术问题

免责声明:本工具仅用于技术学习和研究,请遵守相关法律法规。

相关推荐
WangYaolove131421 小时前
基于python的在线水果销售系统(源码+文档)
python·mysql·django·毕业设计·源码
做人不要太理性21 小时前
CANN Runtime 运行时与维测组件:异构任务调度、显存池管理与全链路异常诊断机制解析
人工智能·自动化
酷酷的崽79821 小时前
CANN 生态可维护性与可观测性:构建生产级边缘 AI 系统的运维体系
运维·人工智能
AALoveTouch21 小时前
大麦网协议分析
javascript·python
做人不要太理性21 小时前
CANN Runtime 运行时组件深度解析:任务调度机制、存储管理策略与维测体系构建逻辑
android·运维·魔珐星云
souyuanzhanvip21 小时前
ServerBox v1.0.1316 跨平台 Linux 服务器管理工具
linux·运维·服务器
池央21 小时前
CANN oam-tools 诊断体系深度解析:自动化信息采集、AI Core 异常解析与 CI/CD 流水线集成策略
人工智能·ci/cd·自动化
依米阳光0821 小时前
Playwright MCP AI实现自动化UI测试
ui·自动化·playwright·mcp
ZH154558913121 小时前
Flutter for OpenHarmony Python学习助手实战:自动化脚本开发的实现
python·学习·flutter
文静小土豆21 小时前
Docker 与 containerd 代理配置详解:镜像拉取速度慢的终极解决方案
运维·docker·容器