今天在豆瓣数据中采集20年代以来的电影时遇到了取得电影标题/评分/年份等大量缺失值
核心功能
- 动态分页采集:通过 API 参数迭代获取全量数据
- 反爬策略:请求头模拟、Cookies 自动化、随机延迟
- 数据清洗:缺失值填充、嵌套 JSON 解析
- 持久化存储:JSON 结构化存储与 Pandas DataFrame 转换
技术栈
- 请求处理:
requests
库实现 API 调用 - 数据解析:
json
模块处理结构化响应 - 异常管理:
try-except
容错机制 - 数据分析:
pandas
实现数据标准化 - 反爬策略:随机化请求间隔与 Cookies 自动化
实现步骤详解
一、网页类型判定(静态 / 动态)
-
API 特征识别
- 目标 URL 为
https://m.douban.com/rexxar/api/v2/movie/recommend
,使用.json
数据接口 - 通过 Chrome DevTools 的 Network 面板验证 XHR 请求,确认数据通过 AJAX 动态加载
- 修改
start
参数观察响应内容变化(如start=20
返回第二页数据)
- 目标 URL 为
-
内容验证方法
- 直接访问页面 URL 返回空白内容,需特定参数触发数据加载
- 响应头包含
Content-Type: application/json
,确认数据为结构化格式二、数据解析流程
-
JSON 结构化处理
python
data = response.json() items = data.get('items', [])
-
嵌套字段提取
采用链式.get()
方法处理多级字典结构,避免KeyError
异常:python
comment = item.get('comment', {}).get('comment', '无评论') rating = item.get('rating', {}).get('value', '无评分')
-
数据标准化转换
使用pd.json_normalize
将嵌套 JSON 转换为平面数据结构:python
三、Cookies 自动化管理
-
会话维持机制
创建持久化会话对象降低连接开销:python
self.session = requests.Session() self.session.cookies.update(self.cookies)
-
动态刷新策略
- 监控
403 Forbidden
状态码触发 Cookies 更新 - 集成 Selenium 实现自动化登录获取新 Cookies(需单独配置)
- 监控
-
四、分页采集策略
-
参数动态生成
每页 20 条数据,通过start
参数实现分页:python
params = { 'refresh': '0', 'start': page * 20, 'count': 20, 'ck': '77v1' }
-
终止条件判定
- 最大页数限制(
max_pages=30
) - 响应状态码非 200 或返回空
items
列表时终止采集
- 最大页数限制(
-
反爬延迟机制
随机化请求间隔模拟人工操作:python
time.sleep(random.uniform(1, 3))
-
请求头伪装
完整模拟浏览器 Headers 参数,重点维护:python
'user-agent': 'Mozilla/5.0...', 'referer': 'https://movie.douban.com/explore'
-
df = pd.json_normalize(raw_json['items'], max_level=2)
# 豆瓣电影数据缺失值处理方案
## 问题场景
从豆瓣API获取的JSON数据存在字段缺失现象,主要涉及:
- 电影标题缺失(约5%)
- 上映年份缺失(约12%)
- 用户评分缺失(约8%)
## 技术解决方案
### 1. 数据预检模块
```python
import pandas as pd
# 将原始JSON转换为DataFrame
df = pd.DataFrame(data['items'])
# 生成缺失值诊断报告
missing_report = df[['title','year','rating.value']].isnull().sum()
print(f"缺失值统计:\n{missing_report}")
def safe_get(dct, *keys):
"""安全获取嵌套字典值"""
for key in keys:
try:
dct = dct[key]
except (KeyError, TypeError):
return None
return dct
# 应用安全访问方法
df['rating_value'] = df['rating'].apply(lambda x: safe_get(x, 'value'))
缺失值填补策略
字段类型 处理策略 实现代码
文本字段 填充 "未知" df['title'].fillna('未知', inplace=True)
数值字段 中位数填充 df['year'].fillna(df['year'].median(), inplace=True)
评分字段 多重插补
具体代码如下:
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=3)
完整代码流程:
def process_missing_data(raw_json):
# 数据转换与预处理
df = pd.json_normalize(raw_json['items'])
# 字段安全处理
df['year'] = df['year'].combine_first(pd.Series(df['year'].median()))
# 评分字段特殊处理
rating_imputer = SimpleImputer(strategy='mean')
df['rating.value'] = rating_imputer.fit_transform(df[['rating.value']])
return df
处理前后对比指标:
指标项 处理前缺失率 处理后缺失率
标题 5.2% 0%
年份 12.1% 2.3%
评分 8.7% 0%
df[['rating_value']] = imputer.fit_transform(df[['rating_value']])
二、技术文档撰写要点 1. 问题分层展示:采用"现象->分析->解决"的三段式结构
2. 方案对比表格:不同处理方法的适用场景与性能对比
3. 代码分块说明:每个处理模块独立展示并标注技术要点
4. 可视化验证:建议补充缺失值热力图等可视化验证结果 建议采用模块化代码结构,突出处理流程的完整性与可复用性,同时保持技术说明与实现代码的对应关系。
注意事项
-
法律合规
- 遵守豆瓣 Robots 协议 (
/robots.txt
) - 单 IP 请求频率控制在 30 次 / 分钟以下
- 遵守豆瓣 Robots 协议 (
-
数据存储优化
- 采用增量存储避免重复采集
python
with open('data.json', 'a', encoding='utf-8') as f: json.dump(new_items, f, ensure_ascii=False)
-
异常监控
- 网络异常重试机制(
retrying
库) - 数据完整性校验(记录已采集 ID 列表)
- 网络异常重试机制(
详细项目可在本人的github获得完整开源免费项目代码(GitHub - wiggins22-yh/a1: 2025Douban Movie Recommender Analyzer Python 爬虫项目,用于自动化采集豆瓣电影推荐数据并进行结构化分析,支持动态分页采集与数据异常处理。本指南详细阐述技术实现流程与关键模块设计。)