跳到主要内容Python 实现 SMZDM 数据处理系统:从爬虫到数据分析 | 极客日志Python
Python 实现 SMZDM 数据处理系统:从爬虫到数据分析
使用 Python 构建 SMZDM 数据处理系统,涵盖数据爬取、清洗、分析及可视化全流程。项目基于 requests 库分析 API 接口进行 POST 请求抓取商品数据,利用 pandas 进行去重、格式化及空值处理,并通过 matplotlib 和 seaborn 展示价格分布、互动趋势及高频词统计。核心模块包括爬虫、清洗与分析,强调反爬策略、错误处理及代码规范,适用于学习端到端数据工程实践。
猫巷少女2.8K 浏览 Python 实现 SMZDM 数据处理系统:从爬虫到数据分析
前言
在大数据时代,数据获取、清洗和分析已成为数据分析师和开发者必备的技能。本文将通过一个完整的实战项目,带你学习如何使用 Python 实现一个完整的数据处理系统,包括数据爬取、清洗、分析和可视化。
本项目以 SMZDM(什么值得买)网站为例,实现了一个端到端的数据处理流程。通过学习本项目,你将掌握:
- Python 爬虫开发技巧
- 数据清洗和预处理方法
- 数据分析和可视化技能
- 完整项目的组织和管理
一、项目概述
1.1 项目简介
本项目是一个完整的 Python 数据处理系统,主要功能包括:
- 数据爬取:从 SMZDM 网站爬取商品数据
- 数据清洗:对原始数据进行去重、格式化等处理
- 数据分析:对清洗后的数据进行多维度分析和可视化
1.2 技术栈
- Python 3.7+
- requests:HTTP 请求库
- pandas:数据处理和分析库
- matplotlib/seaborn:数据可视化库
- jieba:中文分词库
1.3 项目结构
python_excel/
├── crawler.py
├── data_cleaner.py
├── data_analyzer.py
├── main.py
└── requirements.txt
二、环境准备
2.1 安装 Python
确保你的系统已安装 Python 3.7 或更高版本。可以通过以下命令检查:
python --version
2.2 安装依赖包
创建 requirements.txt 文件,内容如下:
requests>=2.31.0
pandas>=2.0.0
matplotlib>=3.7.0
seaborn>=0.12.0
jieba>=0.42.1
然后执行:
pip install -r requirements.txt
三、核心模块实现
3.1 数据爬取模块(crawler.py)
数据爬取是整个数据处理流程的第一步。我们需要分析目标网站的 API 接口,然后编写爬虫代码。
3.1.1 分析 API 接口
通过浏览器开发者工具,我们发现 SMZDM 使用了 API 接口来获取数据。主要的请求信息如下:
- 请求 URL:
https://damo.smzdm.com/interest/more_page
- 请求方法: POST
- 请求参数: 包含页码、分类 ID 等信息
3.1.2 实现爬虫代码
import requests
import json
import pandas as pd
import time
def fetch_page_data(page):
"""爬取单页数据"""
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
}
data = {
'sort': '2',
'page': str(page),
'size': '30',
'category_id': '5324',
}
try:
response = requests.post(
'https://damo.smzdm.com/interest/more_page',
headers=headers,
data=data,
timeout=10
)
response.raise_for_status()
data_json = json.loads(response.text)
items = []
for row in data_json.get('data', {}).get('rows', []):
interaction = row.get('article_interaction', {})
items.append({
'title': row.get('article_title', ''),
'price': row.get('article_price', ''),
'url': row.get('article_url', ''),
'image': row.get('article_pic', ''),
'content': row.get('article_content', ''),
'like': interaction.get('article_worthy', 0),
'comment': interaction.get('article_comment', 0),
'publish_time': row.get('pubdate') or row.get('article_date', '')
})
return items
except Exception as e:
print(f"爬取第 {page} 页时出错:{e}")
return []
def crawl_data(start_page=1, end_page=10, output_file='smzdm_raw.csv', delay=1):
"""爬取多页数据并保存为 CSV"""
all_items = []
for page in range(start_page, end_page + 1):
print(f"正在爬取第 {page} 页...")
items = fetch_page_data(page)
if items:
all_items.extend(items)
print(f"第 {page} 页成功获取 {len(items)} 条数据")
if page < end_page:
time.sleep(delay)
if all_items:
df = pd.DataFrame(all_items)
df.to_csv(output_file, index=False, encoding='utf-8-sig')
print(f"\n数据爬取完成!共获取 {len(all_items)} 条数据")
return output_file
else:
print("未获取到任何数据")
return None
3.1.3 关键要点
- 请求头设置:模拟真实浏览器请求,避免被反爬
- 延迟机制:每次请求之间添加延迟,避免被封禁
- 错误处理:捕获异常,确保程序稳定性
- 数据解析:从 JSON 响应中提取所需字段
3.2 数据清洗模块(data_cleaner.py)
3.2.1 主要清洗任务
- 去重处理:去除完全重复的记录和 URL 重复的记录
- 字段处理:提取价格数字、格式化时间
- 内容清洗:移除 HTML 标签、特殊字符
- 空值处理:处理缺失值
3.2.2 核心代码实现
import pandas as pd
import re
def extract_price(price_str):
"""从价格字符串中提取数字"""
if pd.isna(price_str) or price_str == '':
return None
match = re.search(r'(\d+\.?\d*)', str(price_str))
if match:
try:
return float(match.group(1))
except:
return None
return None
def clean_content(content_str):
"""清洗内容字段,移除 HTML 标签"""
if pd.isna(content_str) or content_str == '':
return ''
content = str(content_str)
content = re.sub(r'<[^>]+>', '', content)
content = re.sub(r'\s+', ' ', content).strip()
return content
def clean_data(input_file='smzdm_raw.csv', output_file='smzdm_cleaned.csv'):
"""数据清洗主函数"""
df = pd.read_csv(input_file, encoding='utf-8-sig')
df = df.drop_duplicates()
df = df.drop_duplicates(subset=['url'], keep='first')
df['price_num'] = df['price'].apply(extract_price)
df['content'] = df['content'].apply(clean_content)
df = df[df['title'].notna() & (df['title'] != '')]
df.to_csv(output_file, index=False, encoding='utf-8-sig')
return output_file
3.2.3 数据清洗技巧
- 正则表达式:使用
re 模块提取和匹配模式
- pandas 函数:使用
drop_duplicates() 去重
- 链式处理:使用
apply() 函数批量处理数据
3.3 数据分析模块(data_analyzer.py)
3.3.1 分析维度
- 价格分析:价格分布、价格统计
- 互动分析:点赞数、评论数分析
- 时间分析:发布时间趋势
- 关联分析:价格与互动的关系
- 文本分析:高频词统计
3.3.2 可视化实现
import matplotlib.pyplot as plt
import seaborn as sns
import jieba
from collections import Counter
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei']
plt.rcParams['axes.unicode_minus'] = False
def analyze_data(input_file='smzdm_cleaned.csv', output_dir='analysis_results'):
"""数据分析主函数"""
df = pd.read_csv(input_file, encoding='utf-8-sig')
price_df = df[df['price_num'].notna()]
plt.figure(figsize=(12, 6))
plt.hist(price_df['price_num'], bins=50, edgecolor='black', alpha=0.7)
plt.xlabel('价格 (元)')
plt.ylabel('商品数量')
plt.title('商品价格分布')
plt.savefig(f'{output_dir}/price_distribution.png', dpi=300)
plt.close()
fig, axes = plt.subplots(1, 2, figsize=(14, 6))
axes[0].hist(df['like'], bins=30, color='#FF6B6B')
axes[0].set_title('点赞数分布')
axes[1].hist(df['comment'], bins=30, color='#4ECDC4')
axes[1].set_title('评论数分布')
plt.savefig(f'{output_dir}/interaction_distribution.png', dpi=300)
plt.close()
top_liked = df.nlargest(10, 'like')
plt.figure(figsize=(12, 8))
plt.barh(range(len(top_liked)), top_liked['like'], color='#FF6B6B')
plt.yticks(
range(len(top_liked)),
[title[:30] + '...' if len(title) > 30 else title for title in top_liked['title']]
)
plt.xlabel('点赞数')
plt.title('热门商品 Top 10')
plt.gca().invert_yaxis()
plt.savefig(f'{output_dir}/top10_liked.png', dpi=300)
plt.close()
all_text = ' '.join(df['title'].dropna().astype(str).tolist())
words = jieba.cut(all_text)
stopwords = set(['的', '了', '在', '是', '我', '有', '和', '就', '不'])
filtered_words = [w for w in words if len(w) >= 2 and w not in stopwords]
word_counts = Counter(filtered_words)
top_words = word_counts.most_common(20)
plt.figure(figsize=(14, 8))
words_list = [word for word, count in top_words]
counts_list = [count for word, count in top_words]
plt.barh(range(len(words_list)), counts_list, color='#FFA07A')
plt.yticks(range(len(words_list)), words_list)
plt.xlabel('出现次数')
plt.title('高频词 Top 20')
plt.gca().invert_yaxis()
plt.savefig(f'{output_dir}/word_frequency.png', dpi=300)
plt.close()
print("数据分析完成!")
3.3.3 可视化要点
- 中文字体设置:确保图表能正确显示中文
- 图表美化:使用合适的颜色、标题、标签
- 高质量输出:设置 DPI 为 300,确保清晰度
四、主程序整合(main.py)
from crawler import crawl_data
from data_cleaner import clean_data
from data_analyzer import analyze_data
def main():
"""主函数:执行完整的数据处理流程"""
print("=" * 60)
print("SMZDM 数据处理系统")
print("=" * 60)
START_PAGE = 1
END_PAGE = 10
RAW_FILE = 'smzdm_raw.csv'
CLEANED_FILE = 'smzdm_cleaned.csv'
print("\n【步骤 1】开始数据爬取...")
crawl_data(start_page=START_PAGE, end_page=END_PAGE, output_file=RAW_FILE, delay=1)
print("\n【步骤 2】开始数据清洗...")
clean_data(RAW_FILE, CLEANED_FILE)
print("\n【步骤 3】开始数据分析...")
analyze_data(CLEANED_FILE, 'analysis_results')
print("\n数据处理流程全部完成!")
if __name__ == '__main__':
main()
五、运行结果
5.1 数据文件
smzdm_raw.csv:原始爬取数据
smzdm_cleaned.csv:清洗后的数据
5.2 分析结果
- 价格分布图:展示商品价格的分布情况
- 互动数据图:展示点赞和评论的分布
- 热门商品 Top10:展示最受欢迎的商品
- 高频词统计:展示商品标题中的热门词汇
- 统计报告:完整的数据统计分析报告
六、项目总结
6.1 技术要点
- 爬虫开发:
- API 接口分析
- 请求头和参数设置
- 数据解析和存储
- 数据处理:
- 数据可视化:
6.2 注意事项
- 遵守法律法规:爬虫要遵守网站的 robots.txt 和法律法规
- 控制爬取频率:避免给服务器造成压力
- 错误处理:完善的异常处理机制
- 代码规范:遵循 PEP8 编码规范
6.3 扩展方向
- 添加数据库存储功能
- 实现定时任务自动爬取
- 开发 Web 界面展示结果
- 添加更多分析维度
- 实现实时监控功能
相关免费在线工具
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online