起因
因为我个人菜的抠脚,把爬失败
的种子数据也当完成
改了状态。
解决办法
所有我现在要通过遍历所有状态为完成
的数据去看结果表里面有没有,如果没有再改回失败
状态。
方案选择
本来想通过mongo的命令直接去搞。但是个人的mongo太深入的也不会,所有还是通过python调用pymongo的方式去改。
小知识点
- 像这种层级结构,查询的时候可以
find({"personClassList.case_title":"XXXXX1"})
用.
来分割。
{
"_id": "XXXXXXX",
"personClassList": [
{
"case_title": "XXXXX1",
}
],
}
- 当数据量特别庞大
find({'status': "完成"})
一次性加载进来,电脑有点吃不消,之前的解决方案是find({'is_merged': 0}).limit(1000)
先查它1000个,防止下次是重复的1000个,就加个字段,通过新加的字段来辨别是否已经遍历过了。
但是我不想改数据,所以找到下面这个方案。全找到,但是每次只返回1000个。缺点是程序不能中断,中断就得重头来,因为我只运行一个所以选择batch_size
的方案。
for content in collection_id.find({'status': "完成"}).batch_size(1000):
print(content.get("case_title"))
- 报了异常pymongo.errors.CursorNotFound: Cursor not found
设置no_cursor_timeout = True,永不超时,游标连接不会主动关闭,需要手动关闭
demos = db['demo'].find({},{"_id": 0},no_cursor_timeout = True)
for cursor in demos:
do_something()
demos.close() # 关闭游标
或者把数搞小一点
find({'status': "完成"}).batch_size(200):
完整代码
mongo_host = "你自己的地址"
mongo_port = 3717
mongo_user = "你自己的用户名"
mongo_passwd = "你的密码"
auth_db = "XXXX"
db_name = "xxxxxx"
def getMCInstance(isAuth=True, isTxMongo=False, dbname="spider_data"):
if isTxMongo:
from txmongo import MongoConnection as MongoClient
else:
from pymongo import MongoClient
if isAuth and mongo_user:
mc = MongoClient(mongo_host, mongo_port)
mc[auth_db].authenticate(mongo_user, mongo_passwd)
return mc
else:
mc = MongoClient(mongo_host)
return mc
mc = getMCInstance()
_mdb = mc[db_name]
from pymongo import UpdateOne
collection_id = _mdb["种子表名"]
collection_detail = _mdb["结果表名"]
reqs = []
for content in collection_id.find({'status': "完成"}).batch_size(1000):
if not collection_detail.find_one({"personClassList.case_title":content.get("case_title")}):
reqs.append(UpdateOne({'_id':content.get('_id')}, {'$set': {'status': "未完成"}}))
print(content.get("case_title"))
if len(reqs)>1000:
collection_id.bulk_write(reqs)
reqs = []
# 最后遍历完 reqs 可能不到1000个,最后一下给他写完。
collection_id.bulk_write(reqs)
网友评论