后端-数据库-publish_time字符串导致SQLite拒绝写入
问题现象
- 爬虫采集的新闻写入数据库时报错:
strptime() argument 1 must be str, not int或 SQLite DateTime 列拒绝字符串类型 - 问题仅出现在网页爬虫模块,微信模块正常
核心问题
根因有两个,按重要性排列:
-
爬虫脚本透传字符串时间:
modules/web-crawler/crawlers/scanner.py:143归一化爬虫返回结果时,直接透传原始publish_time,不做类型转换。爬虫从 HTML/API 解析出的时间是字符串(如"2025-06-15 10:30:00"),不是 Pythondatetime对象。 -
_to_datetime()缺少类型守卫:modules/web-crawler/service.py:11-22的_to_datetime()只捕获ValueError,未检查isinstance(value, str),导致传入int等非预期类型时抛出TypeError而非安全返回None。
对比微信模块(wechat_crawler.py:230-254),其 parse_article_timestamp() 在源头就处理了所有非标准格式(bool、int、毫秒时间戳),最终统一通过 datetime.fromtimestamp() 产出标准 datetime 对象。
解决方法
步骤 1:修复 scanner.py 归一化逻辑
# modules/web-crawler/crawlers/scanner.py
+ from ..service import _to_datetime
normalized.append({
"title": title[:500],
"link": link[:1000],
"content": (item.get("content") or "")[:50000],
- "publish_time": item.get("publish_time") or None,
+ "publish_time": _to_datetime(item.get("publish_time")),
})
步骤 2:增强 _to_datetime 健壮性
# modules/web-crawler/service.py
def _to_datetime(value):
if value is None:
return None
if isinstance(value, datetime):
return value
+ if not isinstance(value, str):
+ return None
for fmt in _TIME_FORMATS:
try:
return datetime.strptime(value, fmt)
except ValueError:
continue
return None
步骤 3:验证修复
cd d:/product/news
venv/Scripts/python.exe -m pytest tests/test_scanner_datetime.py -v
预期 9 个测试全部通过。
下次防错措施
- 快速定位:搜索
WebNews(所有调用点,检查publish_time=赋值前是否有_to_datetime()包装 - 写入验证脚本:
cd d:/product/news
rg "publish_time.*=" modules/web-crawler/ -n | rg -v "_to_datetime" | rg -v "#"
# 应只有 model 定义和 None 赋值,不应有裸字符串赋值
- 流程改进:新增爬虫脚本时,在 CR 中确认
publish_time返回值为 Pythondatetime对象或None,不允许返回字符串