摘要:使用 update_one() 方法而不是 insert_one() 插入数据。

相信你一定有过这样的经历:大晚上好不容易写好一个爬虫,添加了种种可能出现的异常处理,测试了很多遍都没有问题,点击了 RUN 开始正式运行 ,然后美滋滋地准备钻被窝睡觉,睡前还特意检查了下确认没有问题,合上眼后期待着第二天起来,数据都乖乖地躺在 MongoDB 中。第二天早上一睁眼就满心欢喜地冲到电脑前,结果发现爬虫半夜断了,你气得想要砸电脑,然后你看了一下 MongoDB 中爬了一半的数据,在想是删掉重新爬,还是保留下来接着爬。

到这儿问题就来了,删掉太可惜,接着爬很可能会爬到重复数据,虽然后期可以去重,但你有强迫症,就是不想爬到重复数据,怎么办呢?

这就遇到了「爬虫断点续传」问题,关于这个问题的解决方法有很多种,不过本文主要介绍数据存储到 MongoDB 时如何做到只插入新数据,而重复数据自动过滤不插入。

先来个简单例子,比如现在有两个 list ,data2 中的第一条数据和 data 列表中的第一条数据是重复的,我们想将这两个 list 依次插入 MnogoDB 中去, 通常我们会使用 insert_one() 或者 insert_many() 方法插入,这里我们使用 insert_one() 插入,看一下效果。

 1data = [2{'index':'A','name':'James','rank':'1' },3{'index':'B','name':'Wade','rank':'2' },4{'index':'C','name':'Paul','rank':'3' },5]67data2 = [8{'index':'A','name':'James','rank':'1' },9{'index':'D','name':'Anthony','rank':'4' },
10]
11
12import pymongo
13client = pymongo.MongoClient('localhost',27017)
14db = client.Douban
15mongo_collection = db.douban
16
17for i in data:
18    mongo_collection.insert_one(i)

插入第一个 list :

插入第二个 list :

你会发现,重复的数据 A 被插入进去了,那么怎么只插入 D,而不插入 A 呢,这里就要用到 update_one() 方法了,改写一下插入方法:

1for i in data2:
2    mongo_collection.update_one(i,{'$set':i},upsert=True)

这里用到了 $set 运算符,该运算符作用是将字段的值替换为指定的值,upsert 为 True 表示插入。这里也可以用 update() 方法,但是这个方法比较老了,不建议使用。另外尝试使用 update_many() 方法发现不能更新多个相同的值。

1for i in data2:
2    mongo_collection.update(i, i, upsert=True)

下面举一个豆瓣电影 TOP250 的实例,假设我们先获取 10 个电影的信息,然后再获取前 20 个电影,分别用 insert_one() 和 update_one() 方法对比一下结果。

insert_one() 方法会重复爬取前 10 个电影,最终生成 30 个数据:

update_one() 方法则只会插入新的 10 个电影,最终生成 20 个数据:

这就很好了对吧,所以当我们去爬那些需要分页的网站,最好在爬取之前使用 update_one() 方法,这样就算爬虫中断了,也不用担心会爬取重复数据。

代码实现如下:

 1import requests2import json3import csv4import pandas as pd5from urllib.parse import urlencode6import pymongo78client = pymongo.MongoClient('localhost', 27017)9db = client.Douban
10mongo_collection = db.douban
11class Douban(object):
12    def __init__(self):
13        self.url = 'https://api.douban.com/v2/movie/top250?'
14
15    def get_content(self, start_page):
16        params = {
17            'start': start_page,
18            'count': 10
19        }
20        response = requests.get(self.url, params=params).json()
21        movies = response['subjects']
22        data = [{
23            'rating': item['rating']['average'],
24            'genres':item['genres'],
25            'name':item['title'],
26            'actor':self.get_actor(item['casts']),
27            'original_title':item['original_title'],
28            'year':item['year'],
29        } for item in movies]
30
31        self.write_to_mongodb(data)
32
33    def get_actor(self, actors):
34        actor = [i['name'] for i in actors]
35        return actor
36
37    def write_to_mongodb(self, data):
38        for item in data:
39            if mongo_collection.update_one(item, {'$set': item}, upsert=True):
40                # if mongo_collection.insert_one(item):
41                print('存储成功')
42            else:
43                print('存储失败')
44
45    def get_douban(self, total_movie):
46        # 每页10条,start_page循环1次
47        for start_page in range(0, total_movie, 10):
48            self.get_content(start_page)
49
50if __name__ == '__main__':
51    douban = Douban()
52    douban.get_douban(10)

本文完。


推荐阅读:

从函数 def 到类 Class

从 类 Class 到 Scrapy

重复数据_MongoDB 自动过滤重复数据相关推荐

  1. list怎么取数据_MongoDB 自动过滤重复数据

    摘要:使用 update_one() 方法而不是 insert_one() 插入数据. 相信你一定有过这样的经历:大晚上好不容易写好一个爬虫,添加了种种可能出现的异常处理,测试了很多遍都没有问题,点击 ...

  2. Mysql的select in会自动过滤重复的数据

    Mysql的select in会自动过滤重复的数据 默认使用 SELECT 语句: 当加上in范围后,结果如下图: in范围内的数据,如果有重复的,只会选择第一个数据. 所以如果不是直接使用SQL语句 ...

  3. 教你自动过滤重复单号,一键查询物流

    如何通过快递单号查询物流?比如说在导入快递单号的时候,单号重复了,怎么自动过滤重复单号,并快速查询到全部物流呢?不知道如何操作的宝贝们,下面随小编一起来试试. 需要哪些工具? 快递单号若干 怎么快速查 ...

  4. mongodb java 更新数据_MongoDB JAVA API更新数据示例

    [java获得数据库信息常用API(DatabaseMetaData)示例] /** * MongoDBTest * MongoDB更新数据使用示例 */ package com.labci.mong ...

  5. 如何让爬虫工具不自动过滤重复数据

    很多情况下,我们爬取某个网站的数据都需要用到爬虫工具,比如爬山虎,当爬取数据的所有字段都重复时,采集器会自动帮我们过滤掉重复数据,但是如果不想过滤掉重复数据怎么办呢? 解决方法:时间戳. 以爬山虎为例 ...

  6. 快递查询教程,自动过滤重复单号,批量查询快递物流信息

    如何查询快递单号的物流?最好是可以一次性查询的那种,并在导入单号时,可以自动识别重复的单号.那么今天小编给大家分享一个新的技巧,下面一起来试试. 材料准备: 一台Win系统的电脑 多个快递单号 步骤演 ...

  7. 批量查询快递物流,自动过滤重复的单号

    现在电商行业不断的发展,每天要发出的快递都是大量,难免会出现重复的单号,那么如何查询每个单号,如果一个个查询耽误大量的时间.这里就分享一个批量查询,快速过滤出重复的单号.为电商朋友提供查询跟踪方便.下 ...

  8. ios 平滑移动view_iOS 关于列表上拉(平滑加载数据)自动加载数据的问题

    项目需求 我的的列表需要改变,原来的分页加载采用的是MJRefresh框架进行加载更多数据,这需要有一个上拉动作才能触发,而我的产品的意思是当快要滑动到底部时自动加载下一页数据.我自己看了一下,发现很 ...

  9. python读取股票数据_python2自动读取股票数据示例

    一.所需模块pandas_datareader的安装 (python2) [root@DL ~]# pip install pandas_datareader #用conda install pand ...

最新文章

  1. 【建模必备】遗传算法的基本原理与步骤(交叉)
  2. 网络负载均衡-DNS负载均衡
  3. SmartDroid论文阅读
  4. .Net转Java自学之路—基础巩固篇十八(正则)
  5. IntersectionObserve初试
  6. 华为5G又一黑科技曝光!中国通信技术将全球领先
  7. python的随机种子实例
  8. ubuntu14.04(server amd64)免密码sudo
  9. win7搭建oracle,win7下安装Oracle即时客户端搭建
  10. 从零开始写一个武侠冒险游戏-4-第一次整合
  11. 动作捕捉和面部捕捉解决
  12. 解决MATLAB帮助文档打不开的情况
  13. 诗词对仗常用字表(笠翁对韵)
  14. 文件夹怎么加密 怎么给文件夹加密
  15. 关于slam第五讲物平面、归一化平面、像素平面、成像平面的思考
  16. 计算机视觉经典论文的参考论文目录
  17. docker(6)容器的三剑客:docker machine、docker-compose、docker Swarm
  18. 世界上第一台现代电子计算机每秒可进行,世界上第一台现代电子计算机是
  19. svn tree conflict
  20. 吉林大学计算机学院考研大纲,吉林大学计算机科学与技术学院2020考研复试大纲预测...

热门文章

  1. linux脚本安装gcc,在Linux系统下不需要编译安装GCC9,有仓库安装模板脚本
  2. 从键盘上录入学生人数和每个学生的分数,按分数降序输出所有的分数,java冒泡排序应用
  3. mysql和ORTHOMCL_Orthomcl的详细使用
  4. Android测量图像中物体大小,android – 加载图像后测量ImageView
  5. Java 遍历系统根目录
  6. 整数线性规划实现(lingo,python分枝界定法)
  7. 实现option上下移动_Django实战2-自动化运维之配置管理-05:字典管理功能实现
  8. php快废了,PHP为什么要逐渐废弃一些函数?出于什么原因呢?
  9. 白盒测试-条件覆盖-短路陷阱
  10. 『TensorFlow』模型保存和载入方法汇总