Files
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

206 lines
8.4 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.
# 京东法拍房搜索 URL 结构说明
## 一、URL 总体结构
```
https://pro.m.jd.com/mall/active/{activityId}/index.html?{query_params}
```
| 部分 | 值 | 说明 |
|------|-----|------|
| 协议/域名 | `https://pro.m.jd.com` | 京东移动端 H5 活动页服务器 |
| 路径 | `/mall/active/3Rja7L2jmC72Ta8eoa31VFDvaAjf/index.html` | 活动 ID,对应司法拍卖(法拍)频道首页 |
> **最小可用 URL**:路径中的活动 ID 本身就标识了法拍频道,即使不带任何查询参数也能打开法拍首页。
---
## 二、查询参数详解
### 2.1 页面上下文参数(控制页面渲染状态)
| 参数 | 示例值 | 必填 | 说明 |
|------|--------|------|------|
| `pageParam` | `judicature_icon_search_after` | ✅ | 页面状态:从司法图标搜索进入结果页 |
| `pageFrom` | `judicature_search_home` | ✅ | 来源页面:司法搜索首页 |
| `tabParam` | `all` | ✅ | 当前 Tab"all" = 全部 |
| `pageParamMiddle` | `judicature_search_middle` | ✅ | 中间页参数(SSR 渲染需要) |
| `fixSearchParams` | `false` | ❌ | 是否固定搜索条件 |
| `navh` | `49` | ❌ | 导航栏高度(px |
| `stath` | `33` | ❌ | 状态栏高度(px |
### 2.2 搜索条件参数(`spo_` 前缀,核心筛选字段)
| 参数 | 示例值 | 必填 | 说明 |
|------|--------|------|------|
| `spo_keyword` | `塘厦` | ✅ | **搜索关键词**URL 编码) |
| `spo_sortField` | `11` | ✅ | **排序字段**`11` = 按最新发布排序 |
| `spo_multiThirdCateIds` | `15` | ✅ | **类目 ID**`15` = 法拍房 |
| `spo_lat` | `22.599037` | ✅ | 定位纬度(影响搜索结果) |
| `spo_lng` | `114.01689` | ✅ | 定位经度(影响搜索结果) |
| `spo_lbsEffect` | `2` | ✅ | LBS 效果模式 |
| `spo_reqSource` | `1` | ✅ | 请求来源标识 |
### 2.3 设备/位置信息(`tttparams`base64 编码 JSON
原始值是一段 base64 编码,解码后为 JSON 对象,包含:
| 字段 | 示例值 | 说明 |
|------|--------|------|
| `addressId` | `138503600` | 京东地址 ID |
| `d_brand` | `HONOR` | 手机品牌 |
| `model` | `VER-AN10` | 手机型号 |
| `gLat` / `gLng` | `22.623829` / `114.027948` | GPS 定位 |
| `lbsLat` / `lbsLng` | `22.600537` / `114.014698` | LBS 基站定位 |
| `gps_area` | `19_1607_3155_62119` | GPS 区域编码(省_市_区_街道) |
| `un_area` | `19_1607_47388_62139` | 用户区域编码 |
| `scale` | `3` | 屏幕缩放 |
| `os` | `16` | 系统版本 |
> 区域编码 `19_1607_3155_62119` 对应:广东(19)_深圳(1607)_塘厦镇(3155)
### 2.4 时间戳
| 参数 | 示例值 | 说明 |
|------|--------|------|
| `_ts` | `1788869426803` | 毫秒级时间戳 |
### 2.5 UTM 分享/推广追踪
| 参数 | 示例值 | 说明 |
|------|--------|------|
| `utm_user` | `plusmember` | 用户身份 |
| `utm_source` | `androidapp` | 来源平台 |
| `utm_medium` | `appshare` | 分享媒介 |
| `utm_campaign` | `t_335139774` | 活动 ID |
| `utm_term` | `Wxfriends_shareid...` | 微信好友分享 ID |
| `ad_od` | `share` | 广告类型 |
| `gx` / `gxd` | `RnAonzoTNmGdh8lR5Q` / `...` | 京东内部追踪参数 |
---
## 三、完整 URL(脚本实际使用)
```
https://pro.m.jd.com/mall/active/3Rja7L2jmC72Ta8eoa31VFDvaAjf/index.html
?pageParamMiddle=judicature_search_middle
&pageParam=judicature_icon_search_after
&pageFrom=judicature_search_home
&tabParam=all
&fixSearchParams=false
&navh=49
&stath=33
&tttparams=<base64编码的位置信息>
&spo_lng=114.01689
&spo_lbsEffect=2
&spo_reqSource=1
&spo_multiThirdCateIds=15
&spo_lat=22.599037
&spo_keyword=塘厦
&spo_sortField=11
```
> ⚠️ `tttparams`、`spo_lat`、`spo_lng` 等位置参数影响搜索结果范围。早期使用最小 URL 时会漏掉部分房源(如塘厦搜索漏掉 51 条)。
### 可替换的变量
| 变量 | 替换示例 | 说明 |
|------|----------|------|
| `spo_keyword` | `塘厦``长安` | 搜索其他镇/区域 |
| `spo_sortField` | `11`(最新) → 其他值 | 排序方式 |
| `spo_multiThirdCateIds` | `15`(法拍房) → 其他 | 法拍类目 |
---
## 四、排序字段 `spo_sortField` 已知值
| 值 | 排序方式 | 返回状态 | 说明 |
|----|----------|----------|------|
| `0` | 结束时间升序 | 已结束 | 同 `2`,最早在前(2017年起) |
| `1` | — | 进行中 | 当前正在拍卖的房源 |
| `2` | **结束时间升序** | **已结束** | **历史数据抓取用**,最早2017-07,按结束时间从早到晚 |
| `4` | — | 已结束 | 2020年附近数据 |
| `5` | — | 已结束 | 混合年份(2018-2026 |
| `7` | — | 已结束+少量未开始 | 近年数据(2020-2026),混合状态 |
| `8` | — | 进行中 | 当前进行中(不同于 `1` 的排序) |
| `9` | — | 未开始 | 即将开拍的房源 |
| `10` | 结束时间升序 | 已结束 | 同 `2`/`0` |
| `11` | **最新发布** | 未开始/已结束 | **默认值**,按发布时间降序,含即将开拍和近期已结束 |
| `12` | — | 已结束 | 2021-2025年数据 |
| `13` | — | 已结束 | 同 `12` |
| `14` | — | 已结束 | 混合年份(2017-2025 |
| `15` | — | 已结束 | 同 `12` |
| `16`+ | — | — | 无数据 |
### sortField=2 的用途:历史成交数据抓取
`sortField=2` 是获取历史已结束拍卖的关键参数:
- **主要返回已结束(`paimaiStatus=2`)的拍卖**,也会混入少量未开始/进行中的拍卖
- 按**结束时间升序**排列,最早的在前
- 京东平台**最早保留到 2017年7月**(2017-07-04 结束的第一条记录)
- 东莞市关键词总记录数约 46,270 条(全部类目),住宅用房约 20,276 条
- `getSearchDataNum` API 返回 `totalNum` 字段可查询总数
- **⚠️ 无限滚动约100次后停止返回新数据(~4000条硬性上限)**,无法一次获取全量
- 需要按镇/区分区域抓取来突破4000条限制(单个镇通常<4000条,可一次抓全)
> ⚠️ 默认的 `sortField=11`(最新发布)只返回近期上架的房源,无法获取早期历史数据。要抓全量历史成交,必须改用 `sortField=2`。但对于总量>4000条的城市,需按子区域分别抓取。
---
## 五、底层 API 接口
页面通过 JavaScript 动态加载数据,但**第一页数据通过 SSR 内嵌在 HTML 的 `<script>` 标签中**,不经过 API 调用。API 只负责 page 2 及之后的加载。
### 数据来源
| 来源 | 范围 | 获取方式 |
|------|------|----------|
| SSR 内嵌数据 | page 1(约 40 条) | 页面加载后从 `<script>` 标签解析 JSON |
| `getSearchData` API | page 2+ | `page.on("response")` 拦截 API 响应 |
| `getPaimaiCurrentInfoByIdsForApi` | 全部 | 实时拍卖状态(当前价、出价、围观) |
| `getAuctionLabelConfigs` | 部分可见项 | 拍卖标签(一拍、二拍、变卖等) |
> ⚠️ 如果只拦截 API 响应而不提取 SSR 数据,会漏掉 page 1 的全部房源(包括最新发布的房源)。
### API 请求格式
```
POST https://api.m.jd.com/api?appid=paimai&functionId=getSearchData&loginType=2
Content-Type: application/x-www-form-urlencoded
body=<URL编码的JSON>
```
> ⚠️ API 有风险控制(`shieldResult.intercept: true`),直接调用返回 "no access"。需通过浏览器渲染执行风险验证后方可获取数据。
### getSearchData 响应字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `paimaiId` | int | 拍卖 ID(唯一标识) |
| `skuId` | int | 商品 SKU ID |
| `title` | string | 房源标题/地址 |
| `startPrice` | float | 起拍价(元) |
| `currentPrice` | float | 当前价(元) |
| `currentPriceCN` | string | 当前价(中文,如"125.8945万" |
| `discountRate` | float | 折扣率 |
| `paimaiStatus` | int | 拍卖状态:0=未开始, 1=进行中, 2=已结束, 3=已撤回 |
| `auctionType` | int | 拍卖类型:5=司法拍卖 |
| `location` | array | 位置信息 |
| `houseAttributes` | object | 房产属性(见下表) |
| `productImage` | string | 图片路径(CDN |
### houseAttributes 子字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `houseTypeInfo` | string | 户型(如"4室1厅1卫" |
| `housePurpose` | string | 用途(如"住宅" |
| `houseArea` | float | 面积(㎡) |
| `plotName` | string | 小区名称 |
| `averagePrice` | string | 均价(如"8254.40元/平" |
| `houseFloorInfo` | int | 楼层信息 |
| `houseEmpty` | int | 是否空置 |
| `houseCertificate` | int | 权属证书类型 |
| `houseLease` | int | 租赁情况 |