从 0 到 1 打造一个“会自己查数据“的电商 AI 助手:视频热点采集 + 评论分析 + 对话式问答全链路实战
从 0 到 1 打造一个"会自己查数据"的电商 AI 助手:视频热点采集 + 评论分析 + 对话式问答全链路实战
作为一名电商从业者,我每天最关心三件事:同行在卖什么爆款、用户在评论区骂什么问什么、对标账号又发了什么新视频。人工刷抖音效率太低,市面上的数据工具又贵又不灵活。于是我花了一天时间,基于开源爬虫 + SQLite + DeepSeek 大模型,从零搭了一个"放开双手"的 AI 数据助手:它每天自动采集热点视频和评论入库,我随时打开网页就能用自然语言问它问题——问的话题库里没数据?它当场自己去抖音采完再回答我。
本文完整记录从架构设计、核心代码实现到三个关键 Bug 修复的全过程,全部真实代码、真实数据,建议收藏。
一、先想清楚:我到底要什么?
动手之前先把需求拆清楚。电商场景下,一个"真正解放双手"的助手至少要满足四点:
| 需求 | 具体含义 | 技术对应 |
|---|---|---|
| 热点追踪 | 我品类下的爆款视频、上升趋势 | 定时关键词搜索采集 |
| 评论分析 | 用户在骂什么、问什么、想买什么 | 评论入库 + LLM 聚类分析 |
| 对标监控 | 竞对账号发新视频、粉丝变化 | 账号作品轮询 + 快照对比 |
| 随时可问 | 不用等日报,想问就问 | 对话式 Web 界面 + LLM |
最关键的是第四点的升级版体验:我随口问一个它没见过的话题,它应该自己去查数据再回答我,而不是两手一摊说"我不知道",更不能一本正经地瞎编(后面会讲,LLM 真的会瞎编,而且编得很像真的)。
二、技术选型:够用就好,拒绝过度设计
| 模块 | 选型 | 理由 |
|---|---|---|
| 数据采集 | Evil0ctal/Douyin_TikTok_Download_API | 开源、自带 X-Bogus/A-Bogus 签名、支持搜索/评论/主页/解析全套接口,本地 Docker 部署 |
| 存储 | SQLite | 单机数据量不大,零运维,一个文件就是一个库 |
| 后端脚本 | Python 3.13(纯标准库) | 数据采集、HTTP 服务全用 urllib/sqlite3/http.server 实现,零第三方依赖,不用配 venv |
| LLM | DeepSeek API(OpenAI 兼容协议) | 国内直连、便宜、deepseek-v4-flash 约 9 秒响应 |
| 前端 | 单 HTML 文件 | 深色主题聊天页,直接由 Python 的 http.server 托管 |
整个项目不到 800 行代码,跑起来只需要:Docker 容器(爬虫 API)+ 一个 Python 进程(助手服务)。
三、整体架构:四层闭环
┌─────────────────────────────────────────────────────────┐
│ 交互层 Web 聊天页 (localhost:8000) + 定时日报 │
├─────────────────────────────────────────────────────────┤
│ 分析层 DeepSeek LLM(评论聚类/选品建议/防编造约束) │
├─────────────────────────────────────────────────────────┤
│ 存储层 SQLite 四表(videos/comments/accounts/runs) │
├─────────────────────────────────────────────────────────┤
│ 采集层 Python 采集器 → 本地爬虫 API (localhost:8081) │
│ ├─ 定时任务:每天 08:00 / 20:00 自动跑一轮 │
│ └─ 实时触发:对话中检测到缺数据时当场采集 │
└─────────────────────────────────────────────────────────┘
亮点在于采集层有两条通路:定时任务负责"日常巡逻",对话中的实时采集负责"随问随查"——这是实现"放开双手 + 随时可问"的关键设计。
四、核心模块实现
4.1 存储层:四张表撑起全部数据
db.py 里定义了 videos / comments / account_snapshots / collection_runs 四张表。两个设计细节值得说:
- videos 表用
INSERT ... ON CONFLICT DO UPDATE:重复采到同一条视频时只更新点赞数等动态字段,first_seen/last_seen天然支持"这条视频数据涨了多少"的趋势分析; - comments 表用
INSERT OR IGNORE:comment_id唯一约束直接物理去重,返回rowcount就知道是不是新评论。
def upsert_video(self, v: dict) -> None:
self.conn.execute(
"""
INSERT INTO videos (aweme_id, source_type, source_keyword, title,
author_name, digg_count, comment_count, ...)
VALUES (?,?,?,?,?,?,?,...)
ON CONFLICT(aweme_id) DO UPDATE SET
digg_count=excluded.digg_count,
comment_count=excluded.comment_count,
last_seen=excluded.last_seen -- 数据会"长大",趋势就是这么来的
""", (...))
4.2 采集层:限流是保命符
抖音风控敏感,采集器的核心不是"抓得快",而是"活得久"。api_client.py 里强制每次请求间隔 3 秒 + 失败指数退避重试:
def _get(self, path: str, params: dict) -> dict:
# 频率控制:风控敏感,宁可慢不要停
wait = self.interval - (time.time() - self._last_call)
if wait > 0:
time.sleep(wait)
...
for attempt in range(self.retries + 1):
try:
with urllib.request.urlopen(req, timeout=self.timeout) as resp:
payload = json.loads(resp.read().decode("utf-8"))
if payload.get("code") != 200:
raise ApiError(...)
return payload["data"]
except Exception as e:
last_err = e
time.sleep(self.interval * (attempt + 1)) # 退避
Cookie 过期是爬虫的家常便饭,项目里用了一个 Chrome 扩展自动嗅探新 Cookie 并 Webhook 回推给 API 容器,基本实现了 Cookie 保鲜自动化。
4.3 对话层:一次提问的完整旅程
这是整个系统的心脏。用户问"分析一下宝宝辅食的抖音热点趋势",后端发生的事情:
def do_POST(self):
question = payload.get("message").strip()
tokens = _tokens(question) # ① 拆关键词
collect_info = auto_collect(question, tokens) # ② 库不够就当场采
# ③ 把刚用的搜索词传给检索层(关键修复,见后文)
force_keyword = collect_info.get("query", "") \
if collect_info.get("collected") else ""
context = build_context(question, force_keyword)
reply = llm_reply(question, history, context) # ④ 组装上下文送 LLM
auto_collect 的逻辑:先查库里有没有 ≥3 条相关视频,没有就提取搜索词 → 调搜索接口 → 入视频库 → 给 TOP3 视频采评论 → 采账号快照 → 返回采集报告。前端收到 collected 字段后会弹出提示:“📡 刚刚实时采集了 7 条视频 + 13 条评论”。
4.4 LLM 集成:防编造是第一要务
直接把检索结果丢给 LLM 是危险的——它发现库里没数据时,会凭训练记忆给你编一份栩栩如生的假数据(真实踩坑,下文细说)。System Prompt 里必须上硬约束:
SYSTEM_PROMPT = """你是用户的「电商数据助手」……
【最高纪律——绝不允许编造数据】
1. 所有账号信息、视频标题、点赞数、评论内容等具体事实,只能来自下方<数据>区。
2. 如果<数据>里确实没有用户问的内容,必须直接说"这个内容我还没有采集到数据",
绝对禁止凭印象编造任何具体数字。
3. 推测性建议可以有,但必须明确标注"(推测)"或"(建议)",与真实数据严格区分。
以下是助手为你实时检索/采集的相关真实数据:
<数据>
{context}
</数据>"""
再加一道保险:LLM 调用 45 秒超时后自动降级,直接把真实数据原文返回给用户并注明"AI 解读暂不可用"——宁可少一层解读,不让用户干等或拿到超时错误。
五、三个真实踩坑实录(本文最有价值的部分)
坑一:LLM 面不改色地编造数据
现象:我问"分析一下招生办这个账号",它流畅地返回了粉丝数、视频列表、高赞评论——格式完美,内容全假。因为那个账号的数据根本没采过。
根因:提示词只说了"基于数据回答",没有禁止编造的约束。LLM 的天性就是"必须给出答案"。
修复:上面的【最高纪律】prompt。修复后同样的问题再问一个没采过的账号,它会明确回答"我还没有采集到该账号的数据,不会凭印象编造"。做数据类 AI 应用,防幻觉 prompt 不是可选项,是生命线。
坑二:检索失效——长句被当成一个关键词
现象:账号明明已入库,问它却检索不到。
根因:初版 _tokens 把整个中文长句当一个 token,SQL 里执行的是 LIKE '%分析商洛学院招生办公室这个账号%',当然零匹配。
修复:改成 2~4 字滑窗 + 停用词过滤:
def _tokens(text: str) -> list[str]:
cn_segs = re.findall(r"[一-鿿]+", text)
tokens = []
for seg in cn_segs:
for n in (4, 3, 2): # 4字→3字→2字滑窗
for i in range(len(seg) - n + 1):
w = seg[i:i+n]
if w not in _STOPWORDS:
tokens.append(w)
return [w for w in dict.fromkeys(tokens)][:8]
同时检索范围从只搜 title 扩展到 author_name + account_snapshots.nickname——用户问"某某账号"时,名字往往出现在作者字段而不是标题里。
坑三:采集了数据,LLM 却"看不到"(最隐蔽)
现象:问"分析美食探店",系统确实自动采了 7 条视频入库,但 LLM 回答"这批数据的具体内容没有同步到我这边"。采集成功、检索失败,非常诡异。
根因:采集和检索是两条互不相干的路径——
采集路径:搜索词"美食探店热点" → 视频入库(打上 source_keyword 标签)
检索路径:问题拆 token ["美食","探店","热点"] → LIKE 模糊匹配视频标题
token 模糊匹配完全可能命中旧数据、漏掉刚采的新数据。两条路径之间没有任何关联保证。
修复:给 build_context 增加 force_keyword 参数,把采集时用的搜索词直接传进去,按 source_keyword 精确取回刚采的那批数据,彻底绕过脆弱的 token 匹配:
def build_context(question: str, force_keyword: str = "") -> str:
parts = []
if force_keyword:
# 精确路径:刚采集的数据必须进上下文,一条都不许丢
fresh = conn.execute(
"SELECT * FROM videos "
"WHERE source_keyword=? AND source_type='chat_realtime' "
"ORDER BY digg_count DESC LIMIT 10", (force_keyword,)).fetchall()
parts.append("【刚刚实时采集的数据】——请基于这些分析:")
_include_video_batch(conn, parts, fresh, "实时采集")
# ……然后才是常规的 token 模糊检索(作为补充)
经验:数据管道里,"写入"和"读取"必须用同一个键。用模糊匹配做读取键,早晚出事。
六、实战效果
定时巡逻
自动化任务每天 08:00 / 20:00 各跑一轮:检查爬虫容器 → 跑采集 → 导出评论摘要 → 生成五段式洞察报告(购买意向 / 用户痛点 / 价格关注 / 内容反馈 / 行动建议)存入 reports/ 目录。
首份真实报告就挖到了值钱信息:某厨房好物视频(115 万赞)的评论区里,"求链接"类评论密度极高且无一人回复——种草流量在评论区白白流失;有用户明确提出"圆形蒸碟夹"这个市面上没有的产品空白。
随问随查
问"分析宝宝辅食的抖音热点趋势",系统当场采集 7 视频 + 13 评论后回答:
- 采集到的辅食视频点赞均在 27 赞以下——低竞争、高转化的蓝海细分,大博主尚未垄断
- "安排/给孩子安排上"出现 6 次,零负面零比价——决策路径极短,适合直接带货型内容
- 高频词指向"分月龄整套解决方案"比单品推荐更有吸引力
所有数字、账号名、评论原文全部来自刚采的真实数据,可逐条回查数据库。
七、成本与边界
- 金钱成本:DeepSeek API 按 token 计费,一天几毛钱的量级;其余全部本地运行,零费用。
- 风控边界:3 秒/请求的保守限流下连续运行稳定;搜索接口偶发风控时采集器会如实记录失败原因,不会疯狂重试把自己作死。
- 能力边界:目前是"采集 + 分析 + 问答",视频剪辑拆解(下载 → ffmpeg 抽帧 → Whisper 转写 → 多模态拆脚本)是下一步的方向。
八、总结
回头看,这个项目的复杂度不在任何单一技术点,而在把"采集 → 存储 → 检索 → LLM"这条链路焊死:
- 数据类 AI 应用,防幻觉 prompt 是生命线——先说清"不许编",再谈"怎么答";
- 写入和读取用同一个键——
source_keyword精确关联,别信模糊匹配; - 零依赖不是炫技,是可移植性——纯标准库意味着任何装了 Python 的机器
python chat_server.py就能跑; - 小步快跑胜过一步到位——先让"定时采集 + 报告"跑起来,再加对话,再加实时采集,每一步都独立见效。
如果你也是电商/内容从业者,这套"开源爬虫 + SQLite + 国产大模型"的组合拳,一个周末就能复刻一个属于你自己品类的版本。源码结构、prompt 模板、踩坑记录都在文中了,欢迎交流。
技术栈:Python 3.13(纯标准库) / SQLite / FastAPI 爬虫服务 / DeepSeek API / Docker
更多推荐




所有评论(0)