scrapy 中使用 MongoDB 数据库存储抓取到的 IP,判断新抓的 IP 在数据库中是否已经存在,如果存在则不再添加,不存在则插入这条数据,但是执行结果总是不对?

2017-12-03 13:47:11 +08:00
 zyy1245367562
pipelines.py 中的关键代码为:
if db.mycollection.find({"ip":item["ip"]}):
print "{} has already existed.".format(item["ip"])
print db.mycollection.find()
else:
db.mycollection.insert_one(data)
print db.mycollection.count({})
执行的结果总是:
120.25.164.134 has already existed.
<pymongo.cursor.Cursor object at 0x0000000005B330F0>
……
提示我抓取到的每一条数据都是存在的,我的 mycollection 聚集中最开始是空的,为什么会出现这种情况呢?
3405 次点击
所在节点    Python
14 条回复
zyy1245367562
2017-12-03 14:48:52 +08:00
怎么没有前辈来指教一下呢?
tosexxx
2017-12-03 15:09:52 +08:00
大佬都在度假,没空 8 小时之外看 v 站
SO647898
2017-12-03 15:16:03 +08:00
大佬都在度假,没空 8 小时之外看 v 站
kenzh
2017-12-03 15:27:51 +08:00
看了下文档,find()总是返回的是 Cursor, 猜测应该用 db.mycollection.find({"ip":item["ip"]}).count() 吧。
golmic
2017-12-03 15:29:52 +08:00
用 upsert
swulling
2017-12-03 16:19:44 +08:00
brickyang
2017-12-03 19:38:17 +08:00
.find() 返回的是 cursor,用 find().toArray() 返回的是查找结果的数组,如果不存在就是个空数组。

你也可以试试 .findOneAndUpdate() 并设置 upsert: true,这样如果找到记录则更新(更新内容为空),找不到则新建一条记录。
fds
2017-12-03 20:00:39 +08:00
返回的是 cursor,肯定为 True 呀,你得调用.next()才可能获得一个空结果吧。
另外,这种约束条件一般是这样实现:在 ip 上建立一个 unique 的索引,然后每次都直接插入;如果已有,则会报错 duplicate,忽略即可。你这种 ifelse 不是“原子”操作,如果有多个进程同时工作,可能插入多条相同 ip 的。
livexia
2017-12-03 21:32:11 +08:00
find_one
lihongjie0209
2017-12-03 21:38:37 +08:00
动态语言就是有这个问题
如果你需要集合为空:
那么使用 if collection.isEmpty 或者是 if collection.size() == 0

如果你需要集合为 null/none:
那么使用 if collection== null/none

这样写代码的时候意图清楚, 看代码的人也轻松.
zyy1245367562
2017-12-05 19:26:28 +08:00
@kenzh 你的建议可以实现。谢谢。
zyy1245367562
2017-12-05 19:29:16 +08:00
@fds 嗯,你说的对,这一点确实没有考虑到。
zyy1245367562
2017-12-05 19:30:01 +08:00
@lihongjie0209 嗯,受教了。谢谢前辈。
toono
2017-12-06 09:03:17 +08:00
find 方法返回的都是集合对象。

下面我的实际代码,是需要先把查询回来的结果对象使用 count 方法去查看具体数量

def process_item(self, item, spider):
result = self.db[self.mongo_collection].find({'source_url': item['source_url']})
if result.count() != 0:
raise DropItem("Duplicate item found: %s" % item)
else:
return item

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/411545

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX