
pip install pymongo ≠ 能用 mongo 命令
装了 pymongo 只是让 Python 能连 MongoDB,和命令行用 mongo 或 mongod 完全是两回事。很多人卡在这一步:运行 pip install pymongo 后,在终端敲 mongo 报错 command not found,以为装失败了——其实只是没装 MongoDB 服务端本身。
常见错误现象:
- 终端执行
mongo或mongod提示未找到命令 -
import pymongo成功,但pymongo.MongoClient()连不上localhost:27017 - 误以为
pip install pymongo会顺带装好数据库服务(它真不会)
正确做法:
- macOS 用户推荐用
brew install mongodb-community@7.0(最新稳定版),避免手动解压路径混乱 - Linux 用户用包管理器安装(如 Ubuntu 的
apt install mongodb-org),不要用curl + tar手动解压到/usr/local/mongodb—— 容易权限错、PATH 漏加、/data/db目录没建 - Windows 用户直接下官网 MSI 安装包,勾选 “Install as Windows Service”,省去每次手动启停
- 装完务必验证:
mongod --version和mongo --version都应有输出;再跑sudo mkdir -p /data/db && sudo chown $USER /data/db(macOS/Linux)
PyMongo 插入前必须做字段清洗,否则写入会静默失败或结构混乱
MongoDB 是 schema-less,但不等于可以裸奔式插入。爬虫返回的原始数据常含空格、换行、None、HTML 标签、重复键名,直接塞进 collection.insert_one() 容易导致后续查询困难、聚合出错、索引失效。
典型问题场景:
- 职位页抓到的薪资字段是
"¥15K-25K/月 \n ",没 strip 就入库,查的时候得写{"salary": {"$regex": "15K"}} - 价格字段混着中文单位:
"¥99.9元",不转成 float 类型,没法做$gt范围查询 - 详情字段含
<br>、等 HTML 实体,没用BeautifulSoup(text, 'html.parser').get_text()清洗就存进去,前端渲染会出乱码
建议清洗流程(在调用 insert_one 前):
- 对字符串字段统一调用
.strip().replace('\u200b', '').replace('\xa0', ' ')(干掉零宽空格和不间断空格) - 用正则提取数字:
re.search(r'(\d+\.?\d*)', raw_price),捕获后转float,失败则设为None - 日期字段优先转成
datetime对象(用dateutil.parser.parse()或strptime),别存字符串——否则无法用$dateToString或时序聚合 - 布尔字段显式归一化:
is_vip = True if raw_vip in ['是', 'true', '1', True] else False
批量插入时用 insert_many() + ordered=False 避免单条失败中断整个批次
爬虫常一次抓几十上百条,用循环反复调 insert_one() 效率低、网络开销大;但直接上 insert_many() 又怕某一条字段异常(比如超长字符串触发 16MB 限制、ObjectId 冲突、唯一索引冲突)导致整批回滚。
关键参数差异:
-
ordered=True(默认):遇到第一条错误就停,后面全跳过 -
ordered=False:跳过报错那条,继续插剩下的——适合爬虫这种“尽力而为”场景
实操建议:
- 提前对每条文档做轻量校验:
len(doc.get('title', '')) 、<code>isinstance(doc.get('price'), (int, float)) or doc.get('price') is None - 插入后检查结果:
result = collection.insert_many(docs, ordered=False); print(f"成功插入 {len(result.inserted_ids)} 条,跳过 {len(docs) - len(result.inserted_ids)} 条") - 对跳过的文档单独记录日志,方便定位清洗漏点,而不是丢弃
连接 MongoDB 时别硬编码 localhost:27017,用配置抽离 + timeout 控制
本地开发用 MongoClient('localhost', 27017) 没问题,但一旦部署到服务器、Docker 或需要连接云 MongoDB(如 MongoDB Atlas),这个写法立刻崩。更麻烦的是没设超时,网络抖动时 Python 进程会卡死十几秒。
容易踩的坑:
- 环境变量没读取成功,连接串还是
localhost,线上连不到云数据库 - 没设
serverSelectionTimeoutMS=5000,DNS 解析失败时阻塞主线程 - 没关
connect=False,实例化MongoClient时就触发连接探测,影响启动速度
推荐写法:
import os
from pymongo import MongoClient
<p>MONGO_URI = os.getenv("MONGO_URI", "mongodb://localhost:27017")
client = MongoClient(
MONGO_URI,
serverSelectionTimeoutMS=5000,
connect=False # 延迟到第一次操作时才连
)
try:
client.admin.command('ping')
except Exception as e:
print("MongoDB 连接失败:", e)
</p>
真正入库前才调 db.collection.insert_many(),这时才会建立连接。URI 中的用户名、密码、认证库都应从环境变量来,别写死。
最常被忽略的一点:MongoDB 默认不校验文档大小,但单文档上限是 16MB。爬虫如果把整页 HTML 原样塞进一个字段,很容易超限——插入时抛 DocumentTooLarge 异常,且不会告诉你哪条超了。清洗阶段就得主动截断或压缩文本字段,而不是等报错才处理。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











