Files
wiki/skills/jd-fapai-scrape/SKILL.md
T
wiki-agentandClaude Opus 4.6 f06d84a003 Add 东莞法拍房 historical data: 31 sub-regions, 24,949 records (2017-2026)
Scraped all 31 Dongguan sub-regions using sortField=2 (end-time ascending)
to bypass JD's ~4000-item API cap. Merged 34 CSV files by paimaiId into
24,949 unique records covering 2017-07 to 2026-11.

Key findings:
- 上架量 grew ~50x: 98 (2017) → 4,813 (2026)
- 流拍率 peaked at 81.6% (2024), eased to 67.4% (2026)
- 樟木头: 558 records, failure rate peaked 94.2% (2024)
- 塘厦: 205 records, 2026 failure rate 51.0%

Includes: scrape_history.py, batch_scrape_towns.sh, analyze_trends.py,
yearly_stats.py, and updated SKILL.md + url_structure.md documenting
the 4000-item cap and sub-region scraping strategy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-12 02:59:54 +00:00

177 lines
7.9 KiB
Markdown
Raw 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.
---
name: jd-fapai-scrape
description: 抓取京东法拍房搜索结果并支持增量更新。通过 Playwright 渲染京东法拍 H5 页面,拦截 API 响应,提取完整房源数据。支持项目链接、拍卖轮次、智能增量更新(遇到已知数据即停止,不全量下载)。
---
# 京东法拍房源抓取
## 用途
从京东司法拍卖频道搜索结果页抓取全部房源信息:
- 房源标题与地址(完整不截断)
- 项目链接(`https://m.jd.com/product/{skuId}.html`
- 起拍价 / 当前价 / 均价
- 户型 / 面积 / 用途 / 小区名称
- 拍卖轮次(一拍/二拍/变卖,从 API 标签或折扣率推断)
- 拍卖状态 / 出价次数 / 围观人数
- 拍卖开始与结束时间
- 增量追踪字段(`_first_seen` / `_last_seen`
## 前置条件
```bash
pip install playwright
python3 -m playwright install chromium
# 或 apt install chromium-browser
```
## 使用方法
### 首次抓取
```bash
# 默认抓取塘厦镇
python3 skills/jd-fapai-scrape/scrape.py
# 抓取东莞市全部法拍房(~4000 条,约 3 分钟)
python3 skills/jd-fapai-scrape/scrape.py --keyword 东莞市 --output-dir ../法拍/data
# 自定义参数
python3 skills/jd-fapai-scrape/scrape.py --keyword 长安 --sort-field 11 --cate-id 15
```
### 增量更新
```bash
# 加 -i 标志,只下载新房源,遇到已知 paimaiId 即停止
python3 skills/jd-fapai-scrape/scrape.py --keyword 东莞市 --output-dir ../法拍/data -i
```
增量模式的智能行为:
- 读取已有 `{keyword}_法拍房源.json` 中的所有 `paimaiId`
- 按最新发布排序加载(`spo_sortField=11`
- **每加载一批(~40 条)检查是否全部已知**,如果是则立即停止
- 典型增量更新只需加载 1-2 批(~30 秒),而非全量下载 100 批(~3 分钟)
- 新房源添加 `_first_seen``_last_seen` 时间戳
- 已有房源更新可变字段(当前价、状态、出价次数等)并刷新 `_last_seen`
## 去重机制
**去重 key = `paimaiId`(拍卖ID**
- 每次拍卖有唯一的 `paimaiId`,同一房产的一拍和二拍是不同的 `paimaiId`,各自保留
- 不会因为标题相同而合并不同拍卖轮次
- `paimaiId` 对应唯一的详情页 URL`https://m.jd.com/product/{skuId}.html`),等价于按 URL 去重
## 命令行参数
| 参数 | 默认值 | 说明 |
|------|--------|------|
| `--keyword` | 塘厦 | 搜索关键词 |
| `--cate-id` | 15 | 类目 ID15=法拍房) |
| `--sort-field` | 11 | 排序(11=最新发布) |
| `--max-scrolls` | 100 | 最大滚动次数 |
| `--output-dir` | . | 输出目录 |
| `--incremental` / `-i` | false | 增量更新模式 |
## 输出文件
| 文件 | 内容 |
|------|------|
| `{keyword}_法拍房源.csv` | CSV 表格(26 列,最新发布在前) |
| `{keyword}_法拍房源.json` | 完整原始 JSON(含增量追踪字段) |
| `{keyword}_增量日志.log` | 每次增量更新的新增/变更记录(仅增量模式) |
### CSV 列说明
| 列 | 说明 |
|----|------|
| 序号 / 拍卖ID / SKU ID | 唯一标识 |
| 标题 | 完整房产标题 |
| **项目链接** | `https://m.jd.com/product/{skuId}.html` |
| 位置 / 用途 / 户型 / 面积(㎡) / 小区 / 均价 | 房产属性 |
| 起拍价 / 当前价 / 折扣率 | 价格信息 |
| **拍卖轮次** | 一拍/二拍/变卖(API 标签或折扣率推断) |
| **标签** | 全部标签(诉讼资产、低于评估价等) |
| 状态 / 出价次数 / 围观人数 | 拍卖状态 |
| 开始时间 / 结束时间 | 拍卖时间 |
| 拍卖类型 | 司法拍卖等 |
| **首次发现** / **最后更新** | 增量追踪时间戳 |
## 工作原理
1. **Playwright 渲染**headless Chromium 打开京东法拍 H5 页面
2. **SSR 数据提取**:页面加载后从 `<script>` 标签中解析内嵌的 page 1 数据(约 40 条)
3. **API 拦截**:监听 `api.m.jd.com` 响应,捕获三个 API
- `getSearchData`appid=paimai)→ 房源列表 page 2+(标题、价格、户型、面积等)
- `getPaimaiCurrentInfoByIdsForApi` → 实时拍卖状态(当前价、出价、围观)
- `getAuctionLabelConfigs` → 拍卖标签(一拍/二拍/变卖等)
4. **无限滚动**:自动滚动触发加载更多
5. **智能停止**:增量模式下,检测到一批数据全部已知即停止(SSR page 1 和 API 各批都检查)
6. **拍卖轮次推断**:优先用 API 标签,无标签时从折扣率推断(7折≈一拍, 5.6折≈二拍/变卖)
7. **排序**:保持 API 返回顺序(spo_sortField=11 已按发布时间降序),不重新排序
8. **增量合并**:按 `paimaiId` 去重合并,新数据在前,旧数据在后
## 历史数据抓取(sortField=2
默认的 `sortField=11`(最新发布)只返回近期上架的房源。京东平台实际保留了从 **2017年7月** 至今的全部历史成交数据,但需要用 `sortField=2`(按结束时间升序)才能获取。
### ⚠️ 4000条数据上限
京东法拍无限滚动有 **~4000条硬性上限**(约100次滚动后API停止返回新数据),无论排序方式如何。这意味着:
- `sortField=11`(最新发布):返回最近~4000条(约覆盖最近10个月)
- `sortField=2`(结束时间升序):返回最早的~4000条(约覆盖2017-07至~2022
**无法通过一次搜索获取全量历史数据。** 对于总量超过4000条的城市(如东莞市住宅~20,276条),需要按镇/区分区域抓取。
### 按镇/区分区域抓取(推荐)
```bash
# 单个镇(数据量通常<4000,可一次抓全)
python3 skills/jd-fapai-scrape/scrape_history.py \
--keyword 樟木头 --batch-label 樟木头_all \
--max-scrolls 200 --output-dir "output/法拍"
# 批量抓取所有镇(shell脚本循环)
for town in 莞城 东城 南城 万江 ... ; do
python3 skills/jd-fapai-scrape/scrape_history.py \
--keyword "$town" --batch-label "${town}_all" \
--max-scrolls 200 --output-dir "output/法拍"
done
```
合并时用 `analyze_trends.py``paimaiId` 去重:
```bash
python3 skills/jd-fapai-scrape/analyze_trends.py
```
### 大镇的数据缺口
部分大镇(如东城~3998条、南城~3780条)会接近4000条上限,`sortField=2` 的数据覆盖到~2025年。2025年末至2026年的近期数据可通过原始 `scrape.py``sortField=11`)补充,中间有约1年缺口。
### 数据量参考
| 关键词 | 类目 | 总记录数 | sortField=2 实际获取 |
|--------|------|----------|---------------------|
| 东莞市 | 住宅(cate_id=15 | ~20,276 | ~3,9952017至~2022 |
| 樟木头 | 住宅 | ~558 | 5582018至2026,全覆盖) |
| 东城 | 住宅 | ~3,998 | 3,9982017至~2025,触顶) |
| 南城 | 住宅 | ~3,780 | 3,7802018至~2025,触顶) |
> 每页约40条,上限约100次滚动≈4000条。单个镇通常1-3分钟完成。
## 注意事项
- 京东法拍 API 有风控验证,必须通过浏览器渲染,无法直接调用 API
- 页面是 JS SPA,但第一页数据通过 SSR 内嵌在 HTML `<script>` 标签中,需单独提取
- API 只返回 page 2+,只拦截 API 会漏掉 page 1(包括最新发布的房源)
- URL 中的位置参数(`tttparams``spo_lat``spo_lng`)影响搜索结果范围
- API 每页约 40 条,无限滚动约 100 次后停止返回新数据(~4000 条硬性上限),非滚动次数限制
- 历史数据(`sortField=2`)最早到 2017年7月,更早的数据平台已下架
- 京东法拍无独立"已结束"tab`sortField=2` 是获取历史成交的唯一方式
- 大城市(如东莞市)总量超过4000条,需按镇/区分区域抓取才能获取全量历史数据
- `scrape_history.py``getPaimaiCurrentInfoByIdsForApi` 响应捕获需要足够等待时间(初始5秒、滚动间隔3秒),否则结束时间等字段可能为空
- 拍卖标签(一拍/二拍)仅对部分数据能从 API 获取,其余从折扣率推断
- 同一房产的多次拍卖(一拍流拍后二拍)有不同的 `paimaiId`,各自独立保留