最近在分析电商市场趋势时,我经常需要手动收集淘宝商品数据,不仅效率低下还容易出错。于是花了三周时间开发了这个Python爬虫系统,能够自动抓取商品信息并生成可视化报表。这个系统特别适合做市场调研、竞品分析或者价格监控的朋友们使用。
传统的数据收集方式存在几个痛点:首先,手动复制粘贴容易出错;其次,淘宝页面结构复杂,直接采集容易触发反爬;最重要的是,原始数据需要二次处理才能得出有价值的结论。这个系统通过自动化流程解决了这些问题,从数据采集到分析呈现形成完整闭环。
系统采用经典的三层架构:
选择这个技术组合主要考虑:
python复制class TaobaoSpider:
def __init__(self):
self.headers = {...} # 真实浏览器headers
self.proxies = [...] # 代理IP池
def crawl_page(self, keyword, pages=5):
# 实现分页爬取逻辑
def parse_item(self, html):
# 解析商品详情数据
class DataVisualizer:
def __init__(self, df):
self.df = df
def price_distribution(self):
# 生成价格分布图
def sales_analysis(self):
# 生成销量分析图
淘宝的反爬机制非常严格,我们采用了以下应对方案:
请求头伪装:完整复制浏览器headers,特别注意:
IP轮换策略:
验证码处理:
淘宝页面结构复杂,解析时要注意:
python复制def parse_item(self, html):
try:
# 使用CSS选择器定位元素
title = soup.select('.title')[0].get_text(strip=True)
price = soup.select('.price')[0].get('trace-price')
sales = soup.select('.sales')[0].text.replace('人付款','')
# 处理动态加载的数据
shop_info = re.search(r'shopInfo\":(.+?)\}', html).group(1)
shop_name = json.loads(shop_info)['shopName']
except Exception as e:
self.log_error(f"解析失败: {str(e)}")
return None
特别要注意价格和销量字段经常变更class名,需要定期更新选择器。
考虑到商品数据的时序特性,采用MongoDB存储:
json复制{
"_id": ObjectId("..."),
"keyword": "智能手机",
"title": "华为Mate60 Pro",
"price": 6999.00,
"month_sales": 15200,
"shop": "华为官方旗舰店",
"location": "广东深圳",
"timestamp": ISODate("2023-08-20T10:00:00Z"),
"comments": 45200,
"url": "https://item.taobao.com/..."
}
选择MongoDB的原因:
原始数据需要经过以下处理:
使用Pandas进行高效处理:
python复制def clean_data(df):
# 去重
df = df.drop_duplicates('item_id')
# 单位转换
df['price'] = df['price'].astype(float)
df['sales'] = df['sales'].str.extract('(\d+)')[0].astype(int)
# 异常值过滤
df = df[(df['price'] > 1) & (df['price'] < 100000)]
return df
使用Pyecharts生成价格带分布图:
python复制def price_distribution(df):
bins = [0,100,300,500,1000,3000,5000,float('inf')]
labels = ['0-100','100-300','300-500','500-1000','1000-3000','3000-5000','5000+']
price_dist = pd.cut(df['price'], bins=bins, labels=labels).value_counts()
pie = (
Pie()
.add("", price_dist.items())
.set_global_opts(title_opts=opts.TitleOpts(title="价格带分布"))
)
return pie
生成横向柱状图展示热销商品:
python复制def top_sales(df):
top10 = df.nlargest(10, 'sales')[['title', 'sales', 'price']]
bar = (
Bar()
.add_xaxis(top10['title'].tolist())
.add_yaxis("销量", top10['sales'].tolist())
.reversal_axis()
.set_global_opts(
title_opts=opts.TitleOpts(title="销量TOP10"),
xaxis_opts=opts.AxisOpts(name="销量(件)"),
datazoom_opts=[opts.DataZoomOpts()]
)
)
return bar
使用APScheduler实现定时采集:
python复制from apscheduler.schedulers.blocking import BlockingScheduler
sched = BlockingScheduler()
@sched.scheduled_job('cron', day_of_week='mon-fri', hour=10)
def daily_job():
spider = TaobaoSpider()
df = spider.crawl_keywords(['智能手机','笔记本电脑'])
save_to_db(df)
sched.start()
建议采集频率:
使用Flask搭建简易看板:
python复制@app.route('/dashboard/<keyword>')
def dashboard(keyword):
data = get_from_db(keyword)
charts = {
'price': price_distribution(data),
'sales': sales_trend(data),
'top': top_sales(data)
}
return render_template('dashboard.html', charts=charts)
请求重试机制:
数据完整性检查:
python复制def validate_data(df):
required_fields = ['title', 'price', 'sales']
if not all(field in df.columns for field in required_fields):
raise ValueError("缺少必要字段")
if df.isnull().sum().sum() > len(df)*0.1:
raise ValueError("空值过多")
日志监控系统:
Robots协议遵守:
数据使用规范:
版权注意事项:
实现价格异动监测:
python复制def price_alert(item_id):
history = get_history_prices(item_id)
current = get_current_price(item_id)
# 计算Z-Score
zscore = (current - history.mean()) / history.std()
if abs(zscore) > 3: # 3σ原则
send_alert_email(f"价格异常波动: {item_id}")
扩展竞品对比功能:
集成ReportLab生成PDF报告:
这个系统在实际使用中帮我节省了大量手工劳动时间,最惊喜的是发现了几个隐藏的市场机会。比如通过价格带分析发现中端手机市场存在空白点,通过销量趋势预测到了爆款商品。当然也踩过不少坑,最深刻的是有次爬取频率太高导致IP被封,后来通过优化调度策略解决了。