项目背景
创新创业课的数据分析作业要求采集抖音带货达人的样本数据。市面上的收费工具动辄几百元一个月,开源项目又大多停更、接口失效。于是一个想法落地:从零造一个完整可用的采集工具。
场景:创新创业课程数据分析 角色:独立开发 完成时间:2026年5月
核心功能
| 功能 | 说明 |
|---|---|
| 关键词搜索 | 输入话题(如”防晒”、“美妆”),自动搜索抖音相关视频 |
| 达人提取 | 从搜索结果中提取作者,按 sec_uid 去重,支持粉丝数过滤 |
| 带货分析 | 扫描达人主页近期作品,检测是否挂载小黄车/橱窗 |
| Excel 导出 | 输出达人主页链接、昵称、带货视频链接、最新发布时间 |
| 并发加速 | 多位达人同时扫描,三档速度模式可调 |
| GUI 操作 | Tkinter 桌面界面,支持参数配置、进度可视化和结果导出 |
| Cookie 获取 | 浏览器登录提取 / rookiepy / CDP / 剪贴板解析 四种方式 |
| 多轮搜索 | 不同排序方式多轮搜索后合并去重,提高样本覆盖率 |
技术架构
┌──────────────────────────────────────────────┐
│ GUI / CLI │
│ (Tkinter 桌面界面 + argparse 命令行) │
├──────────────────────────────────────────────┤
│ 调度层 (main.py) │
│ 搜索 → 提取作者 → 扫描主页 → 分析 → 导出 │
├──────────┬──────────┬──────────┬─────────────┤
│ crawler/ │ analyzer/│ storage/ │ utils/ │
│ 搜索·主页 │ 过滤·判定 │ Excel导出│ 日志·重试·Cookie│
│ ·详情 │ ·时间解析 │ │ ·浏览器管理 │
├──────────┴──────────┴──────────┴─────────────┤
│ sign/ (a_bogus 签名) │
├──────────────────────────────────────────────┤
│ httpx (异步HTTP) │ Playwright (浏览器自动化) │
└──────────────────────────────────────────────┘
| 模块 | 技术 | 说明 |
|---|---|---|
| 异步 HTTP | httpx | 并发请求引擎,支持连接池复用和自动重试 |
| 加密签名 | gmssl (SM3) | a_bogus 签名算法,通过抖音接口校验 |
| 浏览器自动化 | Playwright | Cookie 提取、登录态维护 |
| Cookie 提取 | rookiepy / CDP / 剪贴板 | 四种策略覆盖不同使用场景 |
| 数据导出 | openpyxl | 结构化 Excel 报表生成 |
| 日志 | loguru | 彩色分级日志,便于调试和问题排查 |
| 环境管理 | python-dotenv | Cookie 等敏感信息通过 .env 管理 |
| GUI | Tkinter | 原生桌面界面,无需额外依赖 |
| 打包 | PyInstaller | 单文件 EXE 交付 |
核心实现
异步采集管线
整个采集流程设计为一条异步流水线:
# 1. 搜索阶段:分页拉取视频列表
async def search_videos(keyword: str, max_results: int) -> list[VideoItem]:
videos = []
cursor = 0
while len(videos) < max_results:
batch = await search_api(keyword, cursor)
if not batch:
break
videos.extend(batch)
cursor = batch[-1].cursor
await asyncio.sleep(SEARCH_INTERVAL)
return videos
# 2. 扫描阶段:并发分析达人的带货特征
async def scan_authors(authors: list[Author], concurrency: int):
semaphore = asyncio.Semaphore(concurrency)
async def scan_one(author):
async with semaphore:
posts = await fetch_user_posts(author.sec_uid)
return analyze_cart_presence(posts)
return await asyncio.gather(*[scan_one(a) for a in authors])
速度控制策略
这是整个项目里踩坑最多也打磨最久的部分。三档速度模式的本质是在”数据获取效率”和”反爬风险”之间找到平衡:
| 模式 | 搜索间隔 | 达人间隔 | 作品间隔 | 适用场景 |
|---|---|---|---|---|
| 安全 | 3~5s | 3~8s | 1~3s | 首次测试、长时间无人值守 |
| 快速 | 1.5~3s | 2~4s | 0.8~1.5s | 日常小规模采集 |
| 极速 | 0.8~1.5s | 1~2.5s | 0.3~0.8s | 少量样本快速验证 |
极速模式下会跳过作品详情 API,仅依赖主页列表中的挂车标记判断。这会牺牲少量准确率(部分”隐式挂车”可能漏判),但能将扫描时间压缩到原来的 1/3。
Cookie 多策略提取
Cookie 是整个工具的”钥匙”。没有有效的登录态,搜索接口直接返回空。为了覆盖各种使用场景,实现了四种提取策略:
| 方式 | 原理 | 适用场景 |
|---|---|---|
| 登录提取 | Playwright 启动 Chromium,用户扫码登录后自动抓取 | 推荐,最可靠 |
| rookiepy | 直接从本地浏览器数据库读取 Cookie | 浏览器已登录,需管理员权限 |
| CDP 提取 | 通过 Chrome DevTools Protocol 连接已打开的浏览器 | 前两种失败时的备选 |
| 剪贴板粘贴 | 解析浏览器 F12 → Copy as cURL 的内容 | 手动获取,最精确 |
项目思考
“能不能在 5 分钟内拿到我想要的数据?”
这是用户唯一关心的问题。httpx 的异步实现、a_bogus 的签名算法、三档速度策略——这些对使用者来说是透明的。他们不需要知道这些,他们只需要一个能工作的工具。
做工程和做研究的区别就在这里:研究追求”怎么做更好”,工程追求”怎么让用户更快拿到结果”。
项目链接
- GitHub:douyin-crawler
