Files
MediaCrawler/docs/项目架构文档.md
程序员阿江(Relakkes) 26c511e35f docs: add project architecture documentation with Mermaid diagrams
添加项目架构文档,包含:
- 系统架构总览图
- 数据流向图
- 爬虫基类体系和生命周期图
- 存储层架构图
- 代理、登录、缓存系统图
- 模块依赖关系图

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 13:16:32 +08:00

22 KiB
Raw Permalink Blame History

MediaCrawler 项目架构文档

1. 项目概述

1.1 项目简介

MediaCrawler 是一个多平台自媒体爬虫框架,采用 Python 异步编程实现,支持爬取主流社交媒体平台的内容、评论和创作者信息。

1.2 支持的平台

平台 代号 主要功能
小红书 xhs 笔记搜索、详情、创作者
抖音 dy 视频搜索、详情、创作者
快手 ks 视频搜索、详情、创作者
B站 bili 视频搜索、详情、UP主
微博 wb 微博搜索、详情、博主
百度贴吧 tieba 帖子搜索、详情
知乎 zhihu 问答搜索、详情、答主

1.3 核心功能特性

  • 多平台支持:统一的爬虫接口,支持 7 大主流平台
  • 多种登录方式二维码、手机号、Cookie 三种登录方式
  • 多种存储方式CSV、JSON、SQLite、MySQL、MongoDB、Excel
  • 反爬虫对策CDP 模式、代理 IP 池、请求签名
  • 异步高并发:基于 asyncio 的异步架构,高效并发爬取
  • 词云生成:自动生成评论词云图

2. 系统架构总览

2.1 高层架构图

flowchart TB
    subgraph Entry["入口层"]
        main["main.py<br/>程序入口"]
        cmdarg["cmd_arg<br/>命令行参数"]
        config["config<br/>配置管理"]
    end

    subgraph Core["核心爬虫层"]
        factory["CrawlerFactory<br/>爬虫工厂"]
        base["AbstractCrawler<br/>爬虫基类"]

        subgraph Platforms["平台实现"]
            xhs["XiaoHongShuCrawler"]
            dy["DouYinCrawler"]
            ks["KuaishouCrawler"]
            bili["BilibiliCrawler"]
            wb["WeiboCrawler"]
            tieba["TieBaCrawler"]
            zhihu["ZhihuCrawler"]
        end
    end

    subgraph Client["API客户端层"]
        absClient["AbstractApiClient<br/>客户端基类"]
        xhsClient["XiaoHongShuClient"]
        dyClient["DouYinClient"]
        ksClient["KuaiShouClient"]
        biliClient["BilibiliClient"]
        wbClient["WeiboClient"]
        tiebaClient["BaiduTieBaClient"]
        zhihuClient["ZhiHuClient"]
    end

    subgraph Storage["数据存储层"]
        storeFactory["StoreFactory<br/>存储工厂"]
        csv["CSV存储"]
        json["JSON存储"]
        sqlite["SQLite存储"]
        mysql["MySQL存储"]
        mongodb["MongoDB存储"]
        excel["Excel存储"]
    end

    subgraph Infra["基础设施层"]
        browser["浏览器管理<br/>Playwright/CDP"]
        proxy["代理IP池"]
        cache["缓存系统"]
        login["登录管理"]
    end

    main --> factory
    cmdarg --> main
    config --> main
    factory --> base
    base --> Platforms
    Platforms --> Client
    Client --> Storage
    Client --> Infra
    Storage --> storeFactory
    storeFactory --> csv & json & sqlite & mysql & mongodb & excel

2.2 数据流向图

flowchart LR
    subgraph Input["输入"]
        keywords["关键词/ID"]
        config["配置参数"]
    end

    subgraph Process["处理流程"]
        browser["启动浏览器"]
        login["登录认证"]
        search["搜索/爬取"]
        parse["数据解析"]
        comment["获取评论"]
    end

    subgraph Output["输出"]
        content["内容数据"]
        comments["评论数据"]
        creator["创作者数据"]
        media["媒体文件"]
    end

    subgraph Storage["存储"]
        file["文件存储<br/>CSV/JSON/Excel"]
        db["数据库<br/>SQLite/MySQL"]
        nosql["NoSQL<br/>MongoDB"]
    end

    keywords --> browser
    config --> browser
    browser --> login
    login --> search
    search --> parse
    parse --> comment
    parse --> content
    comment --> comments
    parse --> creator
    parse --> media
    content & comments & creator --> file & db & nosql
    media --> file

3. 目录结构

MediaCrawler/
├── main.py                 # 程序入口
├── var.py                  # 全局上下文变量
├── pyproject.toml          # 项目配置
│
├── base/                   # 基础抽象类
│   └── base_crawler.py     # 爬虫、登录、存储、客户端基类
│
├── config/                 # 配置管理
│   ├── base_config.py      # 核心配置
│   ├── db_config.py        # 数据库配置
│   └── {platform}_config.py # 平台特定配置
│
├── media_platform/         # 平台爬虫实现
│   ├── xhs/                # 小红书
│   ├── douyin/             # 抖音
│   ├── kuaishou/           # 快手
│   ├── bilibili/           # B站
│   ├── weibo/              # 微博
│   ├── tieba/              # 百度贴吧
│   └── zhihu/              # 知乎
│
├── store/                  # 数据存储
│   ├── excel_store_base.py # Excel存储基类
│   └── {platform}/         # 各平台存储实现
│
├── database/               # 数据库层
│   ├── models.py           # ORM模型定义
│   ├── db_session.py       # 数据库会话管理
│   └── mongodb_store_base.py # MongoDB基类
│
├── proxy/                  # 代理管理
│   ├── proxy_ip_pool.py    # IP池管理
│   ├── proxy_mixin.py      # 代理刷新混入
│   └── providers/          # 代理提供商
│
├── cache/                  # 缓存系统
│   ├── abs_cache.py        # 缓存抽象类
│   ├── local_cache.py      # 本地缓存
│   └── redis_cache.py      # Redis缓存
│
├── tools/                  # 工具模块
│   ├── app_runner.py       # 应用运行管理
│   ├── browser_launcher.py # 浏览器启动
│   ├── cdp_browser.py      # CDP浏览器管理
│   ├── crawler_util.py     # 爬虫工具
│   └── async_file_writer.py # 异步文件写入
│
├── model/                  # 数据模型
│   └── m_{platform}.py     # Pydantic模型
│
├── libs/                   # JS脚本库
│   └── stealth.min.js      # 反检测脚本
│
└── cmd_arg/                # 命令行参数
    └── arg.py              # 参数定义

4. 核心模块详解

4.1 爬虫基类体系

classDiagram
    class AbstractCrawler {
        <<abstract>>
        +start()* 启动爬虫
        +search()* 搜索功能
        +launch_browser() 启动浏览器
        +launch_browser_with_cdp() CDP模式启动
    }

    class AbstractLogin {
        <<abstract>>
        +begin()* 开始登录
        +login_by_qrcode()* 二维码登录
        +login_by_mobile()* 手机号登录
        +login_by_cookies()* Cookie登录
    }

    class AbstractStore {
        <<abstract>>
        +store_content()* 存储内容
        +store_comment()* 存储评论
        +store_creator()* 存储创作者
        +store_image()* 存储图片
        +store_video()* 存储视频
    }

    class AbstractApiClient {
        <<abstract>>
        +request()* HTTP请求
        +update_cookies()* 更新Cookies
    }

    class ProxyRefreshMixin {
        +init_proxy_pool() 初始化代理池
        +_refresh_proxy_if_expired() 刷新过期代理
    }

    class XiaoHongShuCrawler {
        +xhs_client: XiaoHongShuClient
        +start()
        +search()
        +get_specified_notes()
        +get_creators_and_notes()
    }

    class XiaoHongShuClient {
        +playwright_page: Page
        +cookie_dict: Dict
        +request()
        +pong() 检查登录状态
        +get_note_by_keyword()
        +get_note_by_id()
    }

    AbstractCrawler <|-- XiaoHongShuCrawler
    AbstractApiClient <|-- XiaoHongShuClient
    ProxyRefreshMixin <|-- XiaoHongShuClient

4.2 爬虫生命周期

sequenceDiagram
    participant Main as main.py
    participant Factory as CrawlerFactory
    participant Crawler as XiaoHongShuCrawler
    participant Browser as Playwright/CDP
    participant Login as XiaoHongShuLogin
    participant Client as XiaoHongShuClient
    participant Store as StoreFactory

    Main->>Factory: create_crawler("xhs")
    Factory-->>Main: crawler实例

    Main->>Crawler: start()

    alt 启用IP代理
        Crawler->>Crawler: create_ip_pool()
    end

    alt CDP模式
        Crawler->>Browser: launch_browser_with_cdp()
    else 标准模式
        Crawler->>Browser: launch_browser()
    end
    Browser-->>Crawler: browser_context

    Crawler->>Crawler: create_xhs_client()
    Crawler->>Client: pong() 检查登录状态

    alt 未登录
        Crawler->>Login: begin()
        Login->>Login: login_by_qrcode/mobile/cookie
        Login-->>Crawler: 登录成功
    end

    alt search模式
        Crawler->>Client: get_note_by_keyword()
        Client-->>Crawler: 搜索结果
        loop 获取详情
            Crawler->>Client: get_note_by_id()
            Client-->>Crawler: 笔记详情
        end
    else detail模式
        Crawler->>Client: get_note_by_id()
    else creator模式
        Crawler->>Client: get_creator_info()
    end

    Crawler->>Store: store_content/comment/creator
    Store-->>Crawler: 存储完成

    Main->>Crawler: cleanup()
    Crawler->>Browser: close()

4.3 平台爬虫实现结构

每个平台目录包含以下核心文件:

media_platform/{platform}/
├── __init__.py         # 模块导出
├── core.py             # 爬虫主实现类
├── client.py           # API客户端
├── login.py            # 登录实现
├── field.py            # 字段/枚举定义
├── exception.py        # 异常定义
├── help.py             # 辅助函数
└── {特殊实现}.py       # 平台特定逻辑

4.4 三种爬虫模式

模式 配置值 功能描述 适用场景
搜索模式 search 根据关键词搜索内容 批量获取特定主题内容
详情模式 detail 获取指定ID的详情 精确获取已知内容
创作者模式 creator 获取创作者所有内容 追踪特定博主/UP主

5. 数据存储层

5.1 存储架构图

classDiagram
    class AbstractStore {
        <<abstract>>
        +store_content()*
        +store_comment()*
        +store_creator()*
    }

    class StoreFactory {
        +STORES: Dict
        +create_store() AbstractStore
    }

    class CsvStoreImplement {
        +async_file_writer: AsyncFileWriter
        +store_content()
        +store_comment()
    }

    class JsonStoreImplement {
        +async_file_writer: AsyncFileWriter
        +store_content()
        +store_comment()
    }

    class DbStoreImplement {
        +session: AsyncSession
        +store_content()
        +store_comment()
    }

    class SqliteStoreImplement {
        +session: AsyncSession
        +store_content()
        +store_comment()
    }

    class MongoStoreImplement {
        +mongo_base: MongoDBStoreBase
        +store_content()
        +store_comment()
    }

    class ExcelStoreImplement {
        +excel_base: ExcelStoreBase
        +store_content()
        +store_comment()
    }

    AbstractStore <|-- CsvStoreImplement
    AbstractStore <|-- JsonStoreImplement
    AbstractStore <|-- DbStoreImplement
    AbstractStore <|-- SqliteStoreImplement
    AbstractStore <|-- MongoStoreImplement
    AbstractStore <|-- ExcelStoreImplement
    StoreFactory --> AbstractStore

5.2 存储工厂模式

# 以抖音为例
class DouyinStoreFactory:
    STORES = {
        "csv": DouyinCsvStoreImplement,
        "db": DouyinDbStoreImplement,
        "json": DouyinJsonStoreImplement,
        "sqlite": DouyinSqliteStoreImplement,
        "mongodb": DouyinMongoStoreImplement,
        "excel": DouyinExcelStoreImplement,
    }

    @staticmethod
    def create_store() -> AbstractStore:
        store_class = DouyinStoreFactory.STORES.get(config.SAVE_DATA_OPTION)
        return store_class()

5.3 存储方式对比

存储方式 配置值 优点 适用场景
CSV csv 简单、通用 小规模数据、快速查看
JSON json 结构完整、易解析 API对接、数据交换
SQLite sqlite 轻量、无需服务 本地开发、小型项目
MySQL db 性能好、支持并发 生产环境、大规模数据
MongoDB mongodb 灵活、易扩展 非结构化数据、快速迭代
Excel excel 可视化、易分享 报告、数据分析

6. 基础设施层

6.1 代理系统架构

flowchart TB
    subgraph Config["配置"]
        enable["ENABLE_IP_PROXY"]
        provider["IP_PROXY_PROVIDER"]
        count["IP_PROXY_POOL_COUNT"]
    end

    subgraph Pool["代理池管理"]
        pool["ProxyIpPool"]
        load["load_proxies()"]
        validate["_is_valid_proxy()"]
        get["get_proxy()"]
        refresh["get_or_refresh_proxy()"]
    end

    subgraph Providers["代理提供商"]
        kuaidl["快代理<br/>KuaiDaiLiProxy"]
        wandou["万代理<br/>WanDouHttpProxy"]
        jishu["技术IP<br/>JiShuHttpProxy"]
    end

    subgraph Client["API客户端"]
        mixin["ProxyRefreshMixin"]
        request["request()"]
    end

    enable --> pool
    provider --> Providers
    count --> load
    pool --> load
    load --> validate
    validate --> Providers
    pool --> get
    pool --> refresh
    mixin --> refresh
    mixin --> Client
    request --> mixin

6.2 登录流程

flowchart TB
    Start([开始登录]) --> CheckType{登录类型?}

    CheckType -->|qrcode| QR[显示二维码]
    QR --> WaitScan[等待扫描]
    WaitScan --> CheckQR{扫描成功?}
    CheckQR -->|是| SaveCookie[保存Cookie]
    CheckQR -->|否| WaitScan

    CheckType -->|phone| Phone[输入手机号]
    Phone --> SendCode[发送验证码]
    SendCode --> Slider{需要滑块?}
    Slider -->|是| DoSlider[滑动验证]
    DoSlider --> InputCode[输入验证码]
    Slider -->|否| InputCode
    InputCode --> Verify[验证登录]
    Verify --> SaveCookie

    CheckType -->|cookie| LoadCookie[加载已保存Cookie]
    LoadCookie --> VerifyCookie{Cookie有效?}
    VerifyCookie -->|是| SaveCookie
    VerifyCookie -->|否| Fail[登录失败]

    SaveCookie --> UpdateContext[更新浏览器上下文]
    UpdateContext --> End([登录完成])

6.3 浏览器管理

flowchart LR
    subgraph Mode["启动模式"]
        standard["标准模式<br/>Playwright"]
        cdp["CDP模式<br/>Chrome DevTools"]
    end

    subgraph Standard["标准模式流程"]
        launch["chromium.launch()"]
        context["new_context()"]
        stealth["注入stealth.js"]
    end

    subgraph CDP["CDP模式流程"]
        detect["检测浏览器路径"]
        start["启动浏览器进程"]
        connect["connect_over_cdp()"]
        cdpContext["获取已有上下文"]
    end

    subgraph Features["特性"]
        f1["用户数据持久化"]
        f2["扩展和设置继承"]
        f3["反检测能力增强"]
    end

    standard --> Standard
    cdp --> CDP
    CDP --> Features

6.4 缓存系统

classDiagram
    class AbstractCache {
        <<abstract>>
        +get(key)* 获取缓存
        +set(key, value, expire)* 设置缓存
        +keys(pattern)* 获取所有键
    }

    class ExpiringLocalCache {
        -_cache: Dict
        -_expire_times: Dict
        +get(key)
        +set(key, value, expire_time)
        +keys(pattern)
        -_is_expired(key)
    }

    class RedisCache {
        -_client: Redis
        +get(key)
        +set(key, value, expire_time)
        +keys(pattern)
    }

    class CacheFactory {
        +create_cache(type) AbstractCache
    }

    AbstractCache <|-- ExpiringLocalCache
    AbstractCache <|-- RedisCache
    CacheFactory --> AbstractCache

7. 数据模型

7.1 ORM模型关系

erDiagram
    DouyinAweme {
        int id PK
        string aweme_id UK
        string aweme_type
        string title
        string desc
        int create_time
        int liked_count
        int collected_count
        int comment_count
        int share_count
        string user_id FK
        datetime add_ts
        datetime last_modify_ts
    }

    DouyinAwemeComment {
        int id PK
        string comment_id UK
        string aweme_id FK
        string content
        int create_time
        int sub_comment_count
        string user_id
        datetime add_ts
        datetime last_modify_ts
    }

    DyCreator {
        int id PK
        string user_id UK
        string nickname
        string avatar
        string desc
        int follower_count
        int total_favorited
        datetime add_ts
        datetime last_modify_ts
    }

    DouyinAweme ||--o{ DouyinAwemeComment : "has"
    DyCreator ||--o{ DouyinAweme : "creates"

7.2 各平台数据表

平台 内容表 评论表 创作者表
抖音 DouyinAweme DouyinAwemeComment DyCreator
小红书 XHSNote XHSNoteComment XHSCreator
快手 KuaishouVideo KuaishouVideoComment KsCreator
B站 BilibiliVideo BilibiliVideoComment BilibiliUpInfo
微博 WeiboNote WeiboNoteComment WeiboCreator
贴吧 TiebaNote TiebaNoteComment -
知乎 ZhihuContent ZhihuContentComment ZhihuCreator

8. 配置系统

8.1 核心配置项

# config/base_config.py

# 平台选择
PLATFORM = "xhs"  # xhs, dy, ks, bili, wb, tieba, zhihu

# 登录配置
LOGIN_TYPE = "qrcode"  # qrcode, phone, cookie
SAVE_LOGIN_STATE = True

# 爬虫配置
CRAWLER_TYPE = "search"  # search, detail, creator
KEYWORDS = "编程副业,编程兼职"
CRAWLER_MAX_NOTES_COUNT = 15
MAX_CONCURRENCY_NUM = 1

# 评论配置
ENABLE_GET_COMMENTS = True
ENABLE_GET_SUB_COMMENTS = False
CRAWLER_MAX_COMMENTS_COUNT_SINGLENOTES = 10

# 浏览器配置
HEADLESS = False
ENABLE_CDP_MODE = True
CDP_DEBUG_PORT = 9222

# 代理配置
ENABLE_IP_PROXY = False
IP_PROXY_PROVIDER = "kuaidaili"
IP_PROXY_POOL_COUNT = 2

# 存储配置
SAVE_DATA_OPTION = "json"  # csv, db, json, sqlite, mongodb, excel

8.2 数据库配置

# config/db_config.py

# MySQL
MYSQL_DB_HOST = "localhost"
MYSQL_DB_PORT = 3306
MYSQL_DB_NAME = "media_crawler"

# Redis
REDIS_DB_HOST = "127.0.0.1"
REDIS_DB_PORT = 6379

# MongoDB
MONGODB_HOST = "localhost"
MONGODB_PORT = 27017

# SQLite
SQLITE_DB_PATH = "database/sqlite_tables.db"

9. 工具模块

9.1 工具函数概览

模块 文件 主要功能
应用运行器 app_runner.py 信号处理、优雅退出、清理管理
浏览器启动 browser_launcher.py 检测浏览器路径、启动浏览器进程
CDP管理 cdp_browser.py CDP连接、浏览器上下文管理
爬虫工具 crawler_util.py 二维码识别、验证码处理、User-Agent
文件写入 async_file_writer.py 异步CSV/JSON写入、词云生成
滑块验证 slider_util.py 滑动验证码破解
时间工具 time_util.py 时间戳转换、日期处理

9.2 应用运行管理

flowchart TB
    Start([程序启动]) --> Run["run(app_main, app_cleanup)"]
    Run --> Main["执行 app_main()"]
    Main --> Running{运行中}

    Running -->|正常完成| Cleanup1["执行 app_cleanup()"]
    Running -->|SIGINT/SIGTERM| Signal["捕获信号"]

    Signal --> First{第一次信号?}
    First -->|是| Cleanup2["启动清理流程"]
    First -->|否| Force["强制退出"]

    Cleanup1 & Cleanup2 --> Cancel["取消其他任务"]
    Cancel --> Wait["等待任务完成<br/>(超时15秒)"]
    Wait --> End([程序退出])
    Force --> End

10. 模块依赖关系

flowchart TB
    subgraph Entry["入口层"]
        main["main.py"]
        config["config/"]
        cmdarg["cmd_arg/"]
    end

    subgraph Core["核心层"]
        base["base/base_crawler.py"]
        platforms["media_platform/*/"]
    end

    subgraph Client["客户端层"]
        client["*/client.py"]
        login["*/login.py"]
    end

    subgraph Storage["存储层"]
        store["store/"]
        database["database/"]
    end

    subgraph Infra["基础设施"]
        proxy["proxy/"]
        cache["cache/"]
        tools["tools/"]
    end

    subgraph External["外部依赖"]
        playwright["Playwright"]
        httpx["httpx"]
        sqlalchemy["SQLAlchemy"]
        motor["Motor/MongoDB"]
    end

    main --> config
    main --> cmdarg
    main --> Core

    Core --> base
    platforms --> base
    platforms --> Client

    client --> proxy
    client --> httpx
    login --> tools

    platforms --> Storage
    Storage --> sqlalchemy
    Storage --> motor

    client --> playwright
    tools --> playwright

    proxy --> cache

11. 扩展指南

11.1 添加新平台

  1. media_platform/ 下创建新目录
  2. 实现以下核心文件:
    • core.py - 继承 AbstractCrawler
    • client.py - 继承 AbstractApiClientProxyRefreshMixin
    • login.py - 继承 AbstractLogin
    • field.py - 定义平台枚举
  3. store/ 下创建对应存储目录
  4. main.pyCrawlerFactory.CRAWLERS 中注册

11.2 添加新存储方式

  1. store/ 下创建新的存储实现类
  2. 继承 AbstractStore 基类
  3. 实现 store_contentstore_commentstore_creator 方法
  4. 在各平台的 StoreFactory.STORES 中注册

11.3 添加新代理提供商

  1. proxy/providers/ 下创建新的代理类
  2. 继承 BaseProxy 基类
  3. 实现 get_proxy() 方法
  4. 在配置中注册

12. 快速参考

12.1 常用命令

# 启动爬虫
python main.py

# 指定平台
python main.py --platform xhs

# 指定登录方式
python main.py --lt qrcode

# 指定爬虫类型
python main.py --type search

12.2 关键文件路径

用途 文件路径
程序入口 main.py
核心配置 config/base_config.py
数据库配置 config/db_config.py
爬虫基类 base/base_crawler.py
ORM模型 database/models.py
代理池 proxy/proxy_ip_pool.py
CDP浏览器 tools/cdp_browser.py

文档生成时间: 2025-12-18