1. 项目概述
最近在研究生鲜电商的价格波动规律,发现盒马鲜生的"海鲜价"机制很有意思——部分商品价格会根据时段、库存等因素动态调整。作为数据从业者,我决定用Python爬虫抓取这些价格数据进行分析。这个项目不仅适合学习爬虫技术,还能帮助我们理解生鲜电商的定价策略。
2. 技术选型与整体流程
2.1 为什么选择抓包API方式
传统网页爬虫需要解析HTML结构,但现代电商网站大多采用前后端分离架构,数据通过API接口传输。直接调用API有三大优势:
- 数据结构规范,通常是JSON格式
- 无需处理复杂的页面渲染逻辑
- 请求量更小,效率更高
2.2 工具准备清单
- Chrome浏览器 + Developer Tools
- Postman或Insomnia用于API测试
- Python 3.8+
- 主要Python库:
- requests:HTTP请求
- pandas:数据处理
- schedule:定时任务
3. 抓包分析与API定位
3.1 使用Chrome开发者工具
- 打开盒马官网或APP(使用电脑版网页)
- F12打开开发者工具
- 切换到Network选项卡
- 勾选"Preserve log"
- 浏览商品页面,观察XHR请求
3.2 识别关键API
通过筛选发现,商品数据主要通过以下API获取:
code复制https://api.huomao.com/product/v2/detail
请求参数包含:
- product_id:商品ID
- store_id:门店ID
- timestamp:时间戳
4. 爬虫核心实现
4.1 请求头伪装技巧
盒马API有基础的反爬机制,需要设置合理的请求头:
python复制headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Referer': 'https://www.huomao.com/',
'X-Requested-With': 'XMLHttpRequest'
}
4.2 请求参数构造
观察发现API需要以下参数:
python复制params = {
'product_id': '123456',
'store_id': '888',
'timestamp': int(time.time()*1000),
'sign': '动态生成的签名'
}
签名算法逆向分析:
- 使用Charles抓包移动端APP
- 发现sign参数由多个字段拼接后MD5加密
- 具体算法:sign = md5(product_id + store_id + timestamp + secret_key)
4.3 数据处理与存储
API返回的JSON数据结构示例:
json复制{
"data": {
"product": {
"name": "鲜活波士顿龙虾",
"price": 128.0,
"origin_price": 158.0,
"discount": "8.1折",
"inventory": 56
}
}
}
使用pandas进行数据清洗:
python复制def parse_product(data):
product = data['data']['product']
return {
'name': product['name'],
'current_price': product['price'],
'original_price': product.get('origin_price', product['price']),
'discount': product.get('discount', '无'),
'inventory': product['inventory'],
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
5. 定时采集与价格监控
5.1 定时任务实现
使用schedule库设置每30分钟采集一次:
python复制import schedule
import time
def job():
# 采集逻辑
pass
schedule.every(30).minutes.do(job)
while True:
schedule.run_pending()
time.sleep(1)
5.2 价格波动分析
采集一周数据后,可以用pandas进行简单分析:
python复制df = pd.read_csv('huomao_prices.csv')
df['datetime'] = pd.to_datetime(df['timestamp'])
# 按商品分组计算价格波动
price_changes = df.groupby('name')['current_price'].agg(['min', 'max', 'mean'])
price_changes['fluctuation'] = (price_changes['max'] - price_changes['min']) / price_changes['mean']
6. 反爬对抗策略
6.1 常见反爬措施
盒马采用了以下反爬手段:
- 请求频率限制(每分钟约30次)
- 签名验证
- 用户行为检测
6.2 应对方案
- 控制请求间隔:随机延时1-3秒
- 使用代理IP池(注意合规使用)
- 模拟正常用户行为:
- 随机浏览不同商品
- 保持合理的请求顺序
7. 数据可视化
使用matplotlib绘制价格走势图:
python复制import matplotlib.pyplot as plt
def plot_price_trend(product_name):
product_data = df[df['name'] == product_name]
plt.figure(figsize=(12, 6))
plt.plot(product_data['datetime'], product_data['current_price'], 'b-')
plt.title(f'{product_name} 价格走势')
plt.xlabel('时间')
plt.ylabel('价格(元)')
plt.grid()
plt.show()
8. 项目优化方向
8.1 多门店价格对比
扩展采集多个门店数据,分析区域价格差异:
python复制store_ids = ['888', '999', '777'] # 不同门店ID
8.2 价格预测模型
基于历史数据建立时间序列模型(如ARIMA),预测未来价格走势。
8.3 异常价格提醒
设置价格阈值,当出现大幅降价时发送通知:
python复制def check_price_drop(current, previous, threshold=0.2):
return (previous - current) / previous > threshold
9. 注意事项与合规建议
- 严格遵守robots.txt协议
- 控制采集频率,避免影响正常服务
- 数据仅用于个人学习研究
- 不要绕过任何付费接口
- 商业使用需获得授权
10. 常见问题排查
10.1 返回403错误
可能原因:
- 请求头不完整
- IP被限制
解决方案: - 检查请求头是否包含所有必要字段
- 更换IP或增加延时
10.2 数据为空
可能原因:
- 商品ID错误
- 门店未上架该商品
解决方案: - 验证商品ID有效性
- 尝试其他门店ID
11. 个人实战心得
在实际开发中,我发现几个值得注意的点:
- 盒马的API参数会不定期更新,需要定期检查接口变化
- 移动端API的限制通常比网页端宽松
- 价格数据最好配合库存数据一起分析,低库存时的价格波动更有意义
- 周末和工作日的价格模式有明显差异
这个项目最有趣的部分是发现了一些商品的特价规律,比如海鲜类商品通常在晚上8点后会有较大折扣,这对精打细算的消费者很有参考价值。