1. 项目背景与核心价值
做电商数据抓取和分析的朋友应该都遇到过这样的场景:需要批量获取商品详情数据,但官方没有提供完整的API文档。这时候就需要通过技术手段解析网页接口,构建自己的数据采集方案。最近我在做得物App的商品数据采集时,就完整走通了这套流程。
得物作为国内领先的潮流电商平台,其商品数据对市场分析、价格监控、竞品研究都有重要价值。但官方并未开放完整的开发者接口,这就需要我们通过技术手段获取数据。本文将分享从接口发现、参数逆向到数据结构解析的全过程,包含大量实战中积累的经验技巧。
2. 接口发现与请求构造
2.1 接口定位方法
首先需要在App或网页端抓包找到目标接口。我推荐使用Charles或Fiddler这类专业抓包工具,配置手机代理后,在得物App浏览商品时就能捕获到相关请求。
关键识别点:
- 接口路径通常包含"/product/detail"这类关键词
- 请求方法多为GET或POST
- 响应数据为JSON格式且包含完整商品信息
典型得物商品详情接口示例:
https://app.dewu.com/api/v1/product/detail?productId=1234562.2 关键请求参数解析
通过分析多个请求样本,我总结出以下核心参数:
| 参数名 | 类型 | 必填 | 说明 | 示例值 |
|---|---|---|---|---|
| productId | String | 是 | 商品唯一ID | "A123456" |
| platform | String | 否 | 平台标识 | "android" |
| version | String | 否 | App版本号 | "5.9.0" |
| sign | String | 是 | 签名参数 | "a1b2c3d4e5" |
特别注意:sign参数是接口验证的关键,需要通过逆向工程分析其生成算法。根据我的分析,得物采用的是常见的MD5加密方式,将多个参数按特定顺序拼接后加密生成。
2.3 请求头设置技巧
除了URL参数,请求头也需要特别注意以下字段:
headers = { "User-Agent": "Mozilla/5.0 (Linux; Android 10) Dewu/5.9.0", "X-Requested-With": "com.shizhuang.duapp", "Authorization": "Bearer xxxxxxx", # 登录态令牌 "Accept-Encoding": "gzip" }实测发现,得物服务端会校验User-Agent和X-Requested-With字段,如果缺失或格式不正确会返回403错误。Authorization字段在获取某些敏感数据(如库存、价格走势)时需要提供。
3. 响应数据结构深度解析
3.1 基础商品信息结构
典型响应数据采用多层嵌套的JSON结构。以下是核心字段的解析:
{ "code": 0, "message": "success", "data": { "productId": "A123456", "title": "Nike Air Force 1 纯白", "subTitle": "2023新款 经典复刻", "price": 899, "originalPrice": 1299, "discount": "6.9折", "mainImages": [ "https://img.dewu.com/xxx1.jpg", "https://img.dewu.com/xxx2.jpg" ], "specs": [ { "name": "颜色", "values": ["纯白", "米白"] }, { "name": "尺码", "values": ["38", "39", "40"] } ], "stock": 128, "sales": 5600, "brand": { "id": 1001, "name": "Nike" }, "seller": { "shopId": "S888", "shopName": "潮流正品专营店", "rating": 4.9 } } }3.2 特殊字段处理技巧
价格字段:得物采用整数存储价格(单位:分),需要除以100转换。但要注意某些促销价可能直接是元单位,需根据priceType字段判断。
图片URL:图片链接有时会返回相对路径,需要拼接域名前缀。实测发现CDN地址有多个,建议统一替换为"https://img.dewu.com"。
规格参数:specs数组中的值可能存在HTML标签,需要做清洗处理。例如:
import re clean_text = re.sub(r'<[^>]+>', '', dirty_text)
3.3 嵌套数据提取
对于复杂的嵌套数据,建议使用JSONPath或递归函数处理。例如获取所有规格组合:
def extract_specs(data): specs = {} for item in data['data']['specs']: specs[item['name']] = item['values'] return specs4. 反爬机制与应对策略
4.1 常见反爬手段
根据我的实测经验,得物主要采用以下防护措施:
- 请求频率限制:单IP超过30次/分钟会触发验证码
- 签名验证:sign参数错误直接返回403
- 设备指纹:通过HTTP头检测异常设备
- 行为验证:连续访问会弹出滑动验证码
4.2 实战解决方案
IP代理池:建议使用优质住宅代理,按1-2秒间隔请求
proxies = { 'http': 'http://user:pass@proxy_ip:port', 'https': 'https://user:pass@proxy_ip:port' }请求随机化:
- 随机User-Agent(准备至少20个常见手机UA)
- 随机请求间隔(0.5-3秒)
- 随机添加无关参数(如timestamp=xxx)
签名破解:通过逆向App分析sign生成算法,核心逻辑通常是:
def generate_sign(params): secret = '得物密钥' # 需要逆向获取 param_str = '&'.join([f'{k}={v}' for k,v in sorted(params.items())]) return md5(param_str + secret).hexdigest()
5. 数据存储与清洗建议
5.1 数据库设计
推荐使用MongoDB存储非结构化数据,关键字段建立索引:
db.products.createIndex({ "productId": 1, "brand.id": 1, "price": 1 })关系型数据库设计参考:
CREATE TABLE products ( id VARCHAR(20) PRIMARY KEY, title VARCHAR(200), price INT, original_price INT, discount VARCHAR(10), stock INT, sales INT, brand_id INT, shop_id VARCHAR(20), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );5.2 数据清洗要点
- 价格异常值:过滤price>original_price的异常记录
- 图片去重:使用MD5校验去除重复图片URL
- 规格标准化:将"38码/US7"等文本统一转换为数字
- 时间处理:将时间戳转换为标准datetime格式
6. 常见问题排查实录
6.1 接口返回403错误
可能原因:
- 签名计算错误(检查参数顺序和密钥)
- 请求头缺失(特别是User-Agent)
- IP被封禁(更换代理测试)
调试方法:
print(response.request.headers) # 检查发送的请求头 print(response.url) # 检查完整请求URL6.2 数据字段缺失
解决方案:
- 检查接口版本(有些字段只在特定版本返回)
- 添加登录态(部分数据需要认证)
- 确认商品状态(下架商品返回字段较少)
6.3 验证码触发后处理
建议流程:
- 立即停止当前IP的请求
- 更换IP和设备指纹
- 降低请求频率至5次/分钟
- 考虑使用自动化验证码识别服务
7. 性能优化实践
7.1 并发控制策略
使用异步请求提升效率,但要注意得物的频率限制:
import aiohttp import asyncio async def fetch(session, url): async with session.get(url) as response: return await response.json() async def main(): conn = aiohttp.TCPConnector(limit=5) # 控制并发数 async with aiohttp.ClientSession(connector=conn) as session: tasks = [fetch(session, url) for url in urls] return await asyncio.gather(*tasks)7.2 缓存机制实现
对静态数据使用本地缓存:
from diskcache import Cache cache = Cache('tmp/dewu_cache') @cache.memoize(expire=3600) def get_product_detail(product_id): # 接口请求代码8. 法律合规提醒
在进行数据采集时,请特别注意:
- 遵守得物的Robots协议
- 不采集用户隐私数据
- 控制请求频率避免影响正常服务
- 数据仅用于个人分析,不进行商业售卖
建议在夜间低谷期(凌晨1-6点)进行大规模采集,并将请求间隔设置为3秒以上。