cross-platform-products-ai-.../docs/JdDetailReviewsCrawler.md

194 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 京东商品详情与评论抓取方案
- 文档状态Draft
- 更新时间2026-04-03
- 关联任务:`S2-03``S2-04`
## 1. 当前结论
当前阶段,京东商品详情和评论的稳定抓取路径应明确收敛为:
1. 浏览器负责登录、会话校验、模板采集与模板刷新。
2. 服务端负责在授权会话下回放 `api.m.jd.com` 请求,解析商品详情与评论 JSON。
3. 页面 DOM 只用于辅助观测,不应继续作为详情和评论主采集路径。
## 2. 2026-04-03 实时验证结果
基于本地 Playwright 实测,当前京东 PC 商品页的关键链路如下:
1. 搜索页 `https://search.jd.com/Search?keyword=iPhone%2015` 当前可以直接打开,但核心候选数据仍来自 `api.m.jd.com/api?functionId=pc_search_searchWare`
2. 商品页 `https://item.jd.com/100068388535.html` 当前可以直接打开,页面初始化阶段会触发风控与签名相关请求,如 `jra.jd.com/jsTk.do``cactus.jd.com/request_algo`
3. 商品详情主数据来自 `https://api.m.jd.com/?functionId=pc_detailpage_wareBusiness`
4. 评论主数据来自 `https://api.m.jd.com/?functionId=getLegoWareDetailComment`
5. 这两条接口都伴随 `h5st``x-api-eid-token``uuid``appid``client``clientVersion` 等动态上下文,不应假设为匿名公开接口。
## 3. 详情接口
当前实测详情请求形态:
```text
GET https://api.m.jd.com/?functionId=pc_detailpage_wareBusiness
body={
"skuId":"100068388535",
"area":"2_2813_61125_0",
"num":"1",
"sfTime":"1,0,0"
}
appid=pc-item-soa
client=pc
loginType=3
```
当前可稳定解析出的字段:
1. `skuId`
2. `title`
3. `price`
4. `originalPrice`
5. `estimatedPrice`
6. `shopName`
7. `vendorId`
8. `categoryPath`
9. `stockState`
10. `mainImage`
11. `averageScore`
## 4. 评论接口
当前实测评论请求形态:
```text
GET https://api.m.jd.com/?functionId=getLegoWareDetailComment
body={
"shopType":"0",
"sku":100068388535,
"commentNum":5,
"source":"pc"
}
appid=item-v3
client=pc
loginType=3
build=100000
```
当前可稳定解析出的字段:
1. `total`
2. `goodRate`
3. `pictureCount`
4. `tagStatisticsinfoList`
5. `commentInfoList`
评论正文、标签和总量都来自 JSON本轮不建议退回到页面滚动或 DOM 抽取。
## 5. 分页策略
评论分页不要硬编码猜测字段,应以真实抓包模板为准。当前代码已经支持:
1. 保留导入模板中的原始 `body` 结构。
2. 自动重写 `sku` / `skuId` 一类商品标识字段。
3. 自动重写 `commentNum` 一类每页评论数参数。
4. 若模板中存在 `page` / `pageIndex` / `pageNum` / `currentPage` / `commentPage` 之一,则按页递增回放并聚合评论。
5. 多页聚合时按评论 `id` 去重。
注意:
1. 如果导入的评论模板没有页码字段,当前服务会拒绝 `maxPages > 1` 的请求。
2. 想做多页评论回放,建议先在浏览器里翻到评论第 2 页,再抓一次 `getLegoWareDetailComment` 请求作为模板。
## 6. 当前代码落点
`apps/api/src/platforms/jd/live-session.ts` 已补齐以下能力:
1. `previewDetail(skuId)`:详情模板支持换 SKU 回放,不再被初始模板 SKU 锁死。
2. `previewReviews(skuId, { commentCount, page, maxPages })`:评论模板支持页码改写、多页聚合、评论去重。
3. `previewProduct(skuId, options)`:单次返回商品详情与评论,便于后续并入任务执行主链。
4. 对会话失效、模板失效、页码模板缺失和风控验证页做了结构化错误归类,任务编排不再依赖 message contains。
5. 多页评论回放在遇到空页、短页或重复页时会提前收口,避免无效翻页。
新增 API
1. `GET /api/platforms/jd/live-detail-preview`
2. `GET /api/platforms/jd/live-reviews-preview`
3. `GET /api/platforms/jd/live-product-preview`
4. `GET /api/platforms/jd/live-keyword-preview`
`live-keyword-preview` 的目标是补齐最小“关键词直连”闭环:
1. 输入一个关键词。
2. 服务端先调用 `previewSearch(query)` 拉回候选。
3. 依据标题完整命中、关键词片段覆盖、搜索排序位置和可回放 SKU 解析结果自动选一个最匹配候选。
4. 再调用 `previewProduct(skuId, { commentCount, maxPages })` 返回结构化详情和评论。
这条路由不会替代原有“人工确认后执行”的任务主链,但它能让当前系统在会话和模板已准备好的前提下,直接完成“关键词 -> 商品信息 + 评论”验证。
## 7. 浏览器采集模板建议
推荐流程:
1. 在浏览器中登录京东。
2. 打开目标商品页。
3. 在 Network 面板过滤 `pc_detailpage_wareBusiness``getLegoWareDetailComment`
4. 导出:
- Cookie Header
- Detail Request URL
- Reviews Request URL
5. 如果需要多页评论,翻到第 2 页后再抓一条评论请求模板。
6. 把这些值导入 `/api/ops/jd/session-manager/session`,或通过 `/ops/jd/session-manager` 运维页手工注入。
## 8. 当前剩余缺口
这轮已经把京东 `search/detail/reviews` 并入任务主链:
1. 京东会话导入已切到 ops-only Session Manager普通用户页不再暴露登录与恢复入口。
2. `store` 已在 JD live session 可用时切到真实搜索候选与 `previewProduct` 抓取。
3. 报告证据索引已直接引用京东实时商品详情与评论,不再只依赖 mock 候选摘要。
当前剩余缺口主要是:
1. `40/30/30` 抽样已接到真实 JD 评论分页结果,但当前 `hot` 桶仍是基于已抓到评论集合做近似代表性抽样,还没接平台侧专用热评路由。
2. 模板刷新与 `L2` 自动恢复还没落地到执行编排。
3. 真实 AI 归纳仍未替换当前规则化分析层。
4. 评论预算已经按已确认链接和任务总上限分配,但前端结果页还没把每个链接的目标样本数和不足标记显式展示出来。
下一步建议直接推进:
1.`TemplateExpired` / `NeedLogin` / `RiskBlocked` 接到 `S3-02` 的模板刷新与恢复动作。
2. 如果要进一步逼近 PRD 口径,补抓“热评/差评”专用模板或参数模板,而不是只在 merged comment set 上做近似抽样。
3. 用真实评论样本驱动 `S4-02` 的 AI 结构化总结,而不是仅输出规则卡片。
## 9. Ops-Only Session Manager
当前京东登录态维护已经从普通用户流程中剥离,统一收口到后端运维链路:
1. 用户页面只消费抓取结果、任务状态和阻塞说明,不再显示京东登录/恢复入口。
2. 运维页面统一使用 `/ops/jd/session-manager`
3. 后端接口统一使用 `/api/ops/jd/session-manager/*`
4. 老的 `/api/platforms/jd/live-session` 仍保留为兼容入口,但内部已经转交给 Session Manager 处理。
5. 当会话缺失、模板过期或风控拦截时,任务侧会优先展示 Session Manager 的 `publicNote`,提示“后台正在恢复”或“需要人工运维”。
这套设计的目标是:
1. 京东账密、浏览器 profile 和验证码处理逻辑只存在于后端/运维侧,不进入普通任务页面。
2. 自动恢复失败时可切到人工注入最新 Cookie 与模板,但仍不影响前台用户路径。
3. 搜索、详情、评论三段抓取共享同一套受控会话状态,减少“前台能进、后台不能跑”的割裂。
## 10. 环境变量约定
`JdSessionManagerService` 当前支持以下运维环境变量:
1. `JD_OPS_AUTO_ENABLED`
2. `JD_OPS_LOGIN_COMMAND`
3. `JD_OPS_BROWSER_PROFILE_DIR`
4. `JD_OPS_ACCOUNT`
5. `JD_OPS_PASSWORD`
6. `JD_OPS_HEARTBEAT_QUERY`
7. `JD_OPS_CHECK_INTERVAL_MS`
8. `JD_OPS_RUNNER_TIMEOUT_MS`
推荐约定:
1. `JD_OPS_LOGIN_COMMAND` 输出一段 JSON字段与 `JdLiveSessionInput` 一致。
2. JSON 至少应包含 `cookieHeader``detailTemplateUrl``reviewsTemplateUrl`
3. 如果命令链路遇到验证码/短信验证,自动恢复应返回失败,由运维在 `/ops/jd/session-manager` 页面手工注入最新会话。