一次Ozon数据采集的踩坑记录:从被ban到稳定入库
先说结果:折腾了一周,目前稳定每天采集Ozon约2万条商品数据,没有被ban过。 但过程挺曲折的。写出来,供遇到类似问题的同行参考。 4月初,俄罗斯烧烤季的苗头出来了。Wildberries上电烤炉搜索量涨了38%,Ozon的烧烤配件也在涨。 老板让我搭建一套竞品监控系统,核心需求: 我当时觉得这事不难。结果第一天就翻车了。 初始方案很简单: 结果: 问题分析: 免费代理来源基本都是公开的代理池,IP段早就被Ozon拉黑了。连上就403,根本没法用。 痛定思痛,花钱买了某服务商的数据中心代理套餐,配了随机User-Agent轮换: 这次好一些。跑了大概300条请求才开始出现429。 但新的问题出现了: 排查发现,Ozon会根据IP属地返回不同的商品页面。我用的是美国数据中心IP,看到的不是俄罗斯本地用户看到的真实价格和库存。 问题分析: 数据中心IP虽然便宜,但有两个致命问题: 了解到问题出在IP上,我开始找带俄罗斯节点的住宅代理服务商。 最后选了辣椒HTTP,原因: 拿到配置后开始测试: 第一轮测试跑了500条请求,全部成功,没有403,没有429。 关键是用俄罗斯住宅IP访问,返回的商品价格、促销信息、库存状态,和本地用户看到的一致。 IP问题解决了,但还是怕跑太久被风控。做了几层优化: 1. 请求间隔随机化 不要固定间隔,模拟人类操作节奏: 2. 补充完整请求头 3. 会话粘性设置 辣椒HTTP支持会话粘性,可以在采集一个商品的多个页面时保持同一IP: 4. 异常重试 目前每日采集约2万条商品数据的流量消耗: 如果加上静态IP管理店铺账号,9.9元/个/月,性价比确实可以。 回头看,核心卡点其实是两个: 换成俄罗斯住宅IP后,两个问题同时解决了。 一些经验: 这套方案跑了将近两周,目前稳定。不过每个站点的风控策略不一样,仅供参考。 做采集这一年,最大的感受是: IP质量决定数据质量。 尤其做俄罗斯这类独立市场的卖家,本地化数据是选品和定价的基础。用非本土IP采到的数据,轻则决策偏差,重则库存积压。 如果你也在做Ozon或Wildberries的数据采集,建议优先解决两个问题: 有具体问题欢迎交流。技术问题我知道的都会说,商业敏感的就无可奉告了。 以上配置基于实测环境,不同站点策略不同,请根据实际情况调整。辣椒HTTP相关信息来自官网公开资料。一、项目背景
二、第一版方案:requests + 免费代理
import requests
proxies = {
'http': 'http://free-proxy:port',
'https': 'http://free-proxy:port'
}
response = requests.get('https://www.ozon.ru', proxies=proxies)三、第二版方案:数据中心代理 + 随机UA
from fake_useragent import UserAgent
ua = UserAgent()
headers = {'User-Agent': ua.random}
proxies = {...} # 数据中心代理四、第三版方案:住宅代理 + 俄罗斯节点
proxies = {
'http': 'socks5://user:pass@proxy.lajiaohttp.com:port',
'https': 'socks5://user:pass@proxy.lajiaohttp.com:port'
}
response = requests.get(
'https://www.ozon.ru/product/123456',
proxies=proxies,
timeout=15
)五、细节优化:行为模拟
import random
import time
interval = random.uniform(3, 8) # 3-8秒随机间隔
time.sleep(interval)headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'ru-RU,ru;q=0.9,en;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Referer': 'https://www.ozon.ru/'
}# 设置session_id保持会话
session_id = "ozon_bbq_collector_01"
proxies = f"socks5://{session_id}:{password}@proxy.lajiaohttp.com:port"def fetch_with_retry(url, max_retries=3):
for i in range(max_retries):
try:
resp = requests.get(url, headers=headers, proxies=proxies, timeout=10)
if resp.status_code == 200:
return resp.text
except Exception as e:
print(f"第{i+1}次失败: {e}")
time.sleep(5)
return None六、成本核算
项目 数据量 日请求量 ~2万次 平均响应大小 ~50KB 日流量 ~1GB 月流量 ~30GB 月成本(5元/GB) 约150元 七、踩坑总结
八、最终方案架构
┌─────────────────────────────────────────┐
│ 采集任务调度器 │
│ 每天定时触发,按品类分批采集 │
└─────────────────┬───────────────────────┘
▼
┌─────────────────────────────────────────┐
│ 辣椒HTTP代理池 │
│ • 俄罗斯住宅IP(莫斯科/圣彼得堡) │
│ • SOCKS5协议,会话粘性 │
│ • 自动轮换 + 随机延迟 │
└─────────────────┬───────────────────────┘
▼
┌─────────────────────────────────────────┐
│ Ozon数据采集 │
│ • 价格 | 库存 | 评分 | 销量排名 │
│ • 3-8秒随机间隔 │
│ • 异常自动重试 │
└─────────────────┬───────────────────────┘
▼
┌─────────────────────────────────────────┐
│ 数据存储与告警 │
│ • 存入MySQL,每日差异对比 │
│ • 价格波动>10%自动推送 │
└─────────────────────────────────────────┘九、写在最后