High priority: - Fix concurrent race condition for view_count/like_count (atomic update) - Add route request ID tracking to prevent race conditions - Filter get_joke by status=approved (no pending content leak) - Add error feedback for like button Performance: - Optimize random joke query (avoid full table sort) - Limit page_size max to 100 (DoS prevention) Medium: - Add localStorage quota error handling - Handle empty AI response gracefully - Fix generate content title extraction Low: - Add rejected_jokes to stats API - Update dashboard to show rejected count
4.0 KiB
4.0 KiB
采集工具操作文档
概述
采集工具分为两个独立程序:
| 程序 | 功能 | 输出 |
|---|---|---|
site_finder.py |
搜索 Bing,发现笑话聚合网站 | joke_sites.json(站点编号列表) |
site_crawler.py |
按编号或 URL,深度翻页采集笑话 | 直接提交到 API(数据库) |
一、程序 1:发现笑话站点
搜索 Bing 获取笑话聚合网站,保存到 JSON 文件。
# 搜索并保存站点列表(默认输出到 joke_sites.json)
python crawler/site_finder.py
# 指定关键词
python crawler/site_finder.py --keywords "笑话大全,冷笑话,段子"
# 指定输出文件
python crawler/site_finder.py --output my_sites.json
# 限制最多 10 个站点
python crawler/site_finder.py --max-sites 10
# 显示浏览器窗口
python crawler/site_finder.py --no-headless
参数说明:
| 参数 | 默认值 | 说明 |
|---|---|---|
--keywords |
笑话大全,搞笑段子,冷笑话,... | 搜索关键词,逗号分隔 |
--output |
joke_sites.json |
输出 JSON 文件路径 |
--max-sites |
15 | 最多保留几个站点 |
--no-headless |
— | 显示浏览器窗口(不加则无头模式) |
输出格式(joke_sites.json):
[
{
"id": 1,
"url": "https://xiaohua.example.com",
"domain": "xiaohua.example.com",
"title": "笑话大全 - 爆笑来袭",
"found_at": "2026-05-31T10:30:00"
},
{
"id": 2,
"url": "https://joke.example.net",
"domain": "joke.example.net",
"title": "每日一笑",
"found_at": "2026-05-31T10:30:05"
}
]
已有站点会自动保留编号,新站点追加,按域名去重。
二、程序 2:深度采集指定站点
从 JSON 文件按编号加载站点,或直接指定 URL,深度采集该站点所有笑话并提交到 API。
按编号采集(推荐)
# 采集 #1 站点
python crawler/site_crawler.py --id 1
# 批量采集多个站点
python crawler/site_crawler.py --id 1,2,3
# 指定站点文件
python crawler/site_crawler.py --id 1 --sites-file my_sites.json
直接指定 URL
# 直接采集任意 URL
python crawler/site_crawler.py --url https://xiaohua.example.com
python crawler/site_crawler.py --url https://www.52xiaohua.com --no-headless
其他选项
# 显示浏览器窗口
python crawler/site_crawler.py --id 1 --no-headless
# 指定 API 地址
python crawler/site_crawler.py --id 1 --api-base http://192.168.1.10:8001
# 指定管理员账号
python crawler/site_crawler.py --id 1 --username admin --password admin123
参数说明:
| 参数 | 默认值 | 说明 |
|---|---|---|
--id |
— | 站点编号,多个用逗号分隔 |
--url |
— | 直接指定 URL(与 --id 二选一) |
--sites-file |
joke_sites.json |
站点列表文件路径 |
--api-base |
http://localhost:8001 |
API 服务地址 |
--username |
admin |
管理员用户名 |
--password |
admin123 |
管理员密码 |
--no-headless |
— | 显示浏览器窗口 |
三、配合使用流程
# 1. 先启动 API
cd api && uvicorn main:app --reload --port 8001
# 2. 发现笑话站点(建议第一次用 --no-headless 观察效果)
cd crawler && python site_finder.py --no-headless
# 3. 查看生成的站点列表
cat joke_sites.json
# 4. 选择站点编号,开始深度采集
python site_crawler.py --id 1 --no-headless
# 5. 继续采集其他站点
python site_crawler.py --id 2,3 --no-headless
四、采集说明
- 翻页采集:自动发现首页的翻页链接(
?page=N、/page/N/、index_N.html、下一页等),逐页抓取所有笑话 - 去重:基于内容 MD5 哈希去重,同一笑话不会重复入库
- 容错:单个页面失败自动重试 2 次;同一站点连续失败 3 次自动跳过
- 翻页限制:每个站点最多采 30 页,避免无限抓取
- 状态:采集的笑话默认
pending(待审核),需在后台管理页面审核通过后才会在前台展示