LittleCrawler:用一杯咖啡的时间,把小红书、知乎、闲鱼数据“端”回家
核心问题:有没有一套开源、轻量、可扩展的框架,能让开发者在本地一次性把小红书笔记、知乎文章、闲鱼商品的关键信息全量爬下来,并且还能通过 Web 界面随时点两下就跑?
1. 为什么要再写一个爬虫框架?
答案一句话:旧脚本像一次性筷子,写完即弃;LittleCrawler 想做成瑞士军刀,今天爬搜索,明天改个参数就能跑详情,后台还能一键切换 SQLite、MySQL、MongoDB。
1.1 作者亲踩的坑
过去 12 个月,我帮三支小团队写过“小红书关键词监控”“闲鱼价格提醒”“知乎热点收集”三个项目。代码散、依赖乱、登录逻辑一改就崩,最后维护成本比开发成本还高。于是把共性抽象出来:
-
登录抽象成插件(二维码、手机号、Cookie 三选一) -
存储抽象成接口(CSV、JSON、SQLite、MySQL、MongoDB、Excel 六选一) -
任务抽象成“平台+类型”矩阵(xhs/xhy/zhihu × search/detail/creator)
这套抽象落地后,就是 LittleCrawler。
1.2 适用场景速览
| 场景 | 一句话描述 | 对应配置 |
|---|---|---|
| 选品调研 | 每天抓 1 万条“闲鱼+关键词”商品,落地成 Excel 给运营 | PLATFORM=xhy, CRAWLER_TYPE=search, SAVE_DATA_OPTION=excel |
| 热点追踪 | 监控知乎 50 个话题 24h 新增回答,写进 MySQL 做仪表盘 | PLATFORM=zhihu, CRAWLER_TYPE=search, SAVE_DATA_OPTION=db |
| 账号备份 | 把自己 3 年小红书笔记批量导出 JSON,防删帖 | PLATFORM=xhs, CRAWLER_TYPE=creator, SAVE_DATA_OPTION=json |
2. 技术全景:异步 + 反检测 + 可插拔存储
2.1 异步流水线
-
Python 3.11+ 原生 asyncio,单进程就能并发 50+ 浏览器上下文 -
Playwright 负责驱动真实浏览器,绕过 90% 的 JS 指纹检测 -
每张页面解析完立刻写库,内存占用稳定 < 300 MB(实测 1 万条小红书笔记)
2.2 反检测三板斧
-
CDP 模式:启用 ENABLE_CDP_MODE=True,Playwright 通过 Chrome DevTools Protocol 直接连本地浏览器,跳过 WebDriver 特征 -
代理池:内置 services/proxy/目录,可接入免费或付费代理,随机切换出口 IP -
浏览器指纹随机化:User-Agent、WebGL、Canvas 噪音自动加成,每 30 分钟重启一次浏览器实例
2.3 存储层“热插拔”
所有存储实现继承 BaseStorage,新增一个存储只需要 3 个方法:connect()、insert()、close()。
切换存储只需改一行配置:SAVE_DATA_OPTION=sqlite,重启即可,代码零改动。
3. 十分钟跑起来:安装 → 配置 → 第一条数据
3.1 环境准备
# 1) 克隆
git clone https://github.com/pbeenig/LittleCrawler.git
cd LittleCrawler
# 2) 依赖(推荐 uv,比 pip 快 3~5 倍)
uv sync
# 或者老办法
pip install -r requirements.txt
# 3) 浏览器
playwright install chromium
3.2 最小可用配置
编辑 config/base_config.py,保留 4 行即可跑:
PLATFORM = "xhs" # 小红书
KEYWORDS = "露营,咖啡" # 中文关键词逗号分隔
CRAWLER_TYPE = "search" # 先跑搜索
SAVE_DATA_OPTION = "json" # 本地文件最快
3.3 启动 & 结果
python main.py
首次运行会弹出小红书登录二维码,手机扫码即过。完成后数据自动写入 data/xhs_search_YYYYmmdd_HHMMSS.json,单条示例如下:
{
"note_id": "64f8a0000000001b01234567",
"title": "露营咖啡神器,3 分钟手冲",
"desc": "新手无脑入,附价格对比",
"liked_count": 4812,
"user_name": "露营小队长",
"share_time": "2026-01-09 18:34"
}
作者反思
第一次跑 1000 条笔记只用了 4 分钟,但存储格式我选了 CSV,后面做关联查询差点崩溃。建议哪怕只是原型,也优先用 SQLite,省得二次洗数据。
4. Web 后台:把命令行装进浏览器
4.1 一键编译 & 启动
# 前端编译(Next.js + NextUI)
cd web && npm run build
# 启动完整服务(API + 静态页面)
uv run uvicorn api.main:app --port 8080 --reload
浏览器打开 http://127.0.0.1:8080,界面三板块:
-
登录:扫码或填 Cookie 立即生效 -
任务:下拉选平台、类型、关键词,点“Run” -
数据:实时滚动日志,跑完可直接下载 JSON/Excel
4.2 开发模式
如果只做 API 对接,把前端卸掉即可:
API_ONLY=1 uv run uvicorn api.main:app --port 8080 --reload
cd web && npm run dev # 前端热更新,调样式更爽
4.3 界面速览
| 功能 | 截图 | 一句话亮点 |
|---|---|---|
| 登录 | ![]() |
二维码 5 秒刷新,失效自动重拉 |
| 启动 | ![]() |
日志 WebSocket 实时推送,手机也能看进度 |
| 首页 | ![]() |
卡片式任务历史,支持“重新运行” |
5. 深度实战:三个真实任务拆解
5.1 任务 A——小红书“露营”赛道 30 天笔记增量监控
目标:每天抓前 1000 条最新笔记,计算点赞增量,输出 Top 50 爆款。
配置:
PLATFORM = "xhs"
KEYWORDS = "露营"
CRAWLER_TYPE = "search"
SAVE_DATA_OPTION = "sqlite"
落地技巧:
-
SQLite 表加字段 insert_date DATE DEFAULT (date('now')),方便按天分区 -
次日跑任务前,先 SELECT note_id FROM xhs WHERE insert_date = date('now','-1 day'),增量去重 -
用内置 libs/xhs_note_rank.js脚本算涨幅,一键生成 Markdown 榜单,直接贴飞书群
5.2 任务 B——闲鱼“二手相机”价格预警
目标:当富士 X100V 均价低于 4500 元时,推送钉钉机器人。
配置:
PLATFORM = "xhy"
KEYWORDS = "富士X100V"
CRAWLER_TYPE = "search"
SAVE_DATA_OPTION = "mongodb"
落地技巧:
-
MongoDB 聚合管道按 avg(price)每日汇总,低于阈值就调用钉钉 Webhook -
代理务必打开 ENABLE_IP_PROXY=True,否则闲鱼 200 次请求后必弹验证码 -
遇到滑块怎么办?框架自动截图写入 logs/captcha/目录,手动打完滑块把 Cookie 填回 Web 后台即可续跑,无需重启程序
5.3 任务 C——知乎高赞回答备份到本地 Excel
目标:把“2026 春运”话题下前 500 条高赞回答存成 Excel,方便高铁回家路上离线看。
配置:
PLATFORM = "zhihu"
KEYWORDS = "2026春运"
CRAWLER_TYPE = "search"
SAVE_DATA_OPTION = "excel"
落地技巧:
-
Excel 直接生成超链接, =HYPERLINK("https://www.zhihu.com/question/"&A2,"打开"),手机点一下就能跳回答 -
知乎反爬最严,建议 LOGIN_TYPE="cookie",提前在浏览器登录后把z_c0值粘贴到后台,存活 7 天+ -
若出现“请求过于频繁”,框架自动指数退避(最多 5 次,间隔 30 s→5 min),基本零封禁
6. 项目结构走读:5 分钟找到你想改的那一行
LittleCrawler
├── main.py # CLI 入口,argparse 解析
├── config
│ └── base_config.py # 全局配置,所有键都有注释
├── src
│ ├── core
│ │ ├── base_crawler.py # 抽象基类,定义 run()、login()、save()
│ │ └── context.py # 全局 aiohttp 会话、浏览器上下文
│ ├── platforms
│ │ ├── xhs
│ │ │ ├── search.py # 小红书搜索实现
│ │ │ ├── detail.py # 单篇笔记详情
│ │ │ └── creator.py # 指定作者全部笔记
│ │ ├── xhy # 闲鱼同理
│ │ └── zhihu # 知乎同理
│ ├── storage
│ │ ├── base_storage.py # 抽象类
│ │ ├── sqlite_storage.py
│ │ ├── mongodb_storage.py
│ │ └── excel_storage.py # 其余略
│ └── models
│ └── pydantic模型 # 字段校验、类型提示
├── api
│ ├── main.py # FastAPI 路由
│ └── ui # 编译后的 Next.js 静态文件
└── web # 前端源码,pages/api 调后端
快速定位指南
-
想加新平台 → 在 platforms/新建目录,继承BaseCrawler,实现 3 个方法即可 -
想加新存储 → 在 storage/新建类,实现connect/insert/close -
想改扫码逻辑 → 直接改 platforms/xhs/login.py,二维码图片通过 WebSocket 推到前端,无额外耦合
7. 常见踩坑与自救清单
| 症状 | 根因 | 框架内自救方案 |
|---|---|---|
| 扫码后提示“环境异常” | IP 或浏览器指纹被标记 | 启用代理 + CDP 模式,重启浏览器 |
| 闲鱼 403 | 请求缺 header | 框架自动带 x-timestamp x-signature,无需手动干预 |
| MongoDB 写入慢 | 单条 insert 未批量 | 已内置 bulk_write,每 100 条一批 |
| Excel 打不开 | 中文标题被截断 | 使用 openpyxl 并设置 quote_prefix=True,默认修复 |
8. 结论:把脚本升级为产品,只差一个 LittleCrawler
如果你只想一次性抓 200 条数据,curl + grep 也许够用;但当任务变成“每天跑一次、存数据库、给老板看报表”,维护成本就会指数级上升。LittleCrawler 把登录、反爬、存储、调度、可视化全部打包好,让你把精力留给“分析数据”而不是“修脚本”。
作者寄语
开源不是终点,而是协作起点。如果你发现小红书接口又双叒叕改版,欢迎提 PR;只要抽象层不动,平台适配最多 30 行代码就能跟上。愿我们都把时间花在“用数据讲故事”,而不是“和验证码搏斗”。
实用摘要 / 操作清单
-
装环境: uv sync && playwright install chromium -
改配置: PLATFORM/KEYWORDS/SAVE_DATA_OPTION三选一 -
跑起来: python main.py或 Web 后台uvicorn api.main:app -
数据在 data/或数据库,默认表名即平台名 -
扫码失败 → 开代理 + CDP;还是失败 → 换 Cookie 登录 -
想定时 → Linux crontab -e加一行cd /path && uv run python main.py -
想扩展 → 继承 BaseCrawler或BaseStorage,写 3 个方法即可
One-page Summary
LittleCrawler = Python 3.11 异步框架 + Playwright 反检测 + FastAPI/Next.js 控制台。
支持小红书、闲鱼、知乎 3 平台,搜索/详情/作者 3 类任务,CSV/JSON/SQLite/MySQL/MongoDB/Excel 6 种存储。
安装 3 行命令,配置 4 行代码,Web 扫码登录,日志实时推送。
开源 MIT,结构清晰,平台或存储均可热插拔,适合把“一次性脚本”升级为“定时数据产品”。
FAQ
-
问:是否支持 Windows?
答:完全支持, playwright 自动下载 chromium,无需手动装 Chrome。 -
问:扫码登录能维持多久?
答:小红书约 30 天,知乎 7 天,闲鱼 2~3 天,失效后 Web 后台一键重新扫码即可。 -
问:我想同时跑多个关键词怎么办?
答:在KEYWORDS用英文逗号分隔,或起多个容器/进程分别指定不同配置文件即可。 -
问:会不会侵犯平台版权?
答:框架仅抓取公开页面,且提供限速、退避机制,请遵守各平台 robots 协议及当地法律,商用前务必评估合规。 -
问:数据量大了以后如何增量更新?
答:所有存储实现都内置upsert,以note_id/question_id/item_id为主键;次日跑任务自动去重。 -
问:可以 headless 跑在服务器吗?
答:可以,设置HEADLESS=True即可;若遇验证码,可手动在本机扫完后把 Cookie 贴到服务器继续。 -
问:想抓抖音/B 站行不行?
答:抽象层已留好,按platforms/现有结构新增目录即可,预计编码量 < 200 行。




