Pydantic v2 原生兼容 Python 3.11,需明确安装 >=2.0 版本并使用 BaseModel、model_config 和 field_validator;解析爬虫数据时应预处理脏数据、合理设默认值、单条捕获 ValidationError 并记录上下文。

Pydantic v2 与 Python 3.11 兼容性确认
Pydantic v2(即 pydantic>=2.0)原生支持 Python 3.11,无需降级或额外适配。但要注意:如果你误装了旧版 pydantic(v1),在 Python 3.11 下运行会报 ImportError: cannot import name 'Field' from 'pydantic' 或类似错误——因为 v1 的 BaseModel 和字段定义方式已彻底变更。
实操建议:
立即学习“Python免费学习笔记(深入)”;
Python 编程规范与最佳实践。强制 PEP 8 代码风格、语法校验、单元测试执行,适用于代码编写、审查和重构。触发词:Python、代码规范、py_compile、单元测试。
- 用
pip install "pydantic>=2.0"明确指定 v2,避免 pip 自动选错版本 - 检查是否残留 v1:运行
python -c "import pydantic; print(pydantic.VERSION)",输出应为2.x.x - v2 中所有模型必须继承
pydantic.BaseModel,不再支持 v1 的class Config写法,改用model_config字典或@model_validator装饰器
爬虫响应体直接转 Pydantic 模型的典型流程
常见场景是解析 JSON API 响应(如 requests.get(...).json()),但原始数据常含空字符串、缺失字段、类型错位(比如数字字段传了字符串),直接传给 BaseModel 构造会失败。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 先用
response.json()获取 dict,再传入模型;不要试图对 raw bytes 或 str 调用.parse_obj()(v2 已弃用) - 对可能为空/缺失的字段,用
Optional[Type]+ 默认值(None或Field(default=None)) - 对字符串数字字段(如
"price": "99.9"),在字段类型中直接写float,Pydantic v2 会自动尝试转换;若需严格校验,加@field_validator('price')手动处理 - 示例:
from pydantic import BaseModel, field_validator class Product(BaseModel): id: int name: str price: float tags: list[str] = [] @field_validator('tags') @classmethod def ensure_tags_list(cls, v): if v is None: return [] return v
处理 HTML 解析后的脏数据(如 BeautifulSoup 输出)
BeautifulSoup 提取的文本常带空白、换行、Unicode 零宽字符,甚至 None。Pydantic 的 @field_validator 是清洗入口,但注意:验证器只在字段赋值时触发,不会自动处理嵌套 dict 的深层键。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 清洗逻辑尽量放在字段级验证器里,而非在爬虫主逻辑中预处理——保持职责分离,也方便复用模型
- 对文本字段,用
str.strip()+re.sub(r'\s+', ' ', ...)去多余空白;避免在验证器里做耗时操作(如网络请求) - 若提取结果是
bs4.Tag对象,先调用.get_text()再传入模型,不要把 Tag 实例直接塞进字段 - 遇到字段必须存在但 HTML 中可能完全缺失的情况,用
Field(default=...)或Field(default_factory=list),避免ValidationError
异常捕获与部分失败容忍
真实爬虫中,单条数据结构异常很常见(比如某商品缺价格)。若整个批次因一条失败而中断,就违背了“尽力而为”的原则。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 对每条待解析数据单独 try/except
ValidationError,记录日志并跳过,而不是让整个for item in items:循环崩溃 - 用
Product.model_validate(item, strict=False)(v2.6+)可放宽类型检查,比如允许 int 当 float 用;但不推荐长期依赖,应明确数据契约 - 调试时临时加
print(Product.model_json_schema())查看字段约束和默认行为,比反复读文档快 - 别在模型里做业务逻辑判断(如 “价格不能为负” 应该由业务层决定是否过滤,而非在
@field_validator中 raise ValueError)
ValidationError 都附带原始 item 的 repr 或 hash,否则 debug 时根本不知道哪条脏数据触发了问题。

















