爬虫数据使用MongDB保存时自动过滤重复数据
本文转载自以下网站: 爬虫断了?一招搞定 MongoDB 重复数据 https://www.makcyun.top/web_scraping_withpython13.html
需要学习的地方:
MongDB数据库的初步使用
import pymongo
client = pymongo.MongoClient('localhost', 27017) # 链接
db = client.Douban # 数据库
mongo_collection = db.douban # 数据库中的数据表
def write_to_mongodb(self, data):
for item in data:
if mongo_collection.update_one(item, {'$set': item}, upsert=True):
# if mongo_collection.insert_one(item):
print('存储成功')
else:
print('存储失败')
MongoDB 避免插入重复数据。
摘要:尽量使用 update_one() 方法而不是 insert_one() 插入数据。
相信你一定有过这样的经历:大晚上好不容易写好一个爬虫,添加了种种可能出现的异常处理,测试了很多遍都没有问题,点击了 RUN 开始正式运行 ,然后美滋滋地准备钻被窝睡觉,睡前还特意检查了下确认没有问题,合上眼后期待着第二天起来,数据都乖乖地躺在 MongoDB 中。第二天早上一睁眼就满心欢喜地冲到电脑前,结果发现爬虫半夜断了,你气得想要砸电脑,然后你看了一下 MongoDB 中爬了一半的数据,在想是删掉重新爬,还是保留下来接着爬。
到这儿问题就来了,删掉太可惜,接着爬很可能会爬到重复数据,虽然后期可以去重,但你有强迫症,就是不想爬到重复数据,怎么办呢?
这就遇到了「爬虫断点续传」问题,关于这个问题的解决方法有很多种,不过本文主要介绍数据存储到 MongoDB 时如何做到只插入新数据,而重复数据自动过滤不插入。
先来个简单例子,比如现在有两个 list ,data2 中的第一条数据和 data 列表中的第一条数据是重复的,我们想将这两个 list 依次插入 MnogoDB 中去, 通常我们会使用 insert_one() 或者 insert_many() 方法插入,这里我们使用 insert_one() 插入,看一下效果。
data = [ |
插入第一个 list :

插入第二个 list :

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

这里用到了 $set 运算符,该运算符作用是将字段的值替换为指定的值,upsert 为 True 表示插入。这里也可以用 update() 方法,但是这个方法比较老了,不建议使用。另外尝试使用 update_many() 方法发现不能更新多个相同的值。
for i in data2: |
下面举一个豆瓣电影 TOP250 的实例,假设我们先获取 10 个电影的信息,然后再获取前 20 个电影,分别用 insert_one() 和 update_one() 方法对比一下结果。
insert_one() 方法会重复爬取 前 10 个电影的数据:

update_one() 方法则只会插入新的 10 个电影的数据:

这就很好了对吧,所以当我们去爬那些需要分页的网站,最好在爬取之前使用 update_one() 方法,这样就算爬虫中断了,也不用担心会爬取重复数据。
代码实现如下:
import requests
import json
import csv
import pandas as pd
from urllib.parse import urlencode
import pymongo client = pymongo.MongoClient('localhost', 27017)
db = client.Douban
mongo_collection = db.douban
class Douban(object):
def __init__(self):
self.url = 'https://api.douban.com/v2/movie/top250?' def get_content(self, start_page):
params = {
'start': start_page,
'count': 10
}
response = requests.get(self.url, params=params).json()
movies = response['subjects']
data = [{
'rating': item['rating']['average'],
'genres':item['genres'],
'name':item['title'],
'actor':self.get_actor(item['casts']),
'original_title':item['original_title'],
'year':item['year'],
} for item in movies] self.write_to_mongodb(data) def get_actor(self, actors):
actor = [i['name'] for i in actors]
return actor def write_to_mongodb(self, data):
for item in data:
if mongo_collection.update_one(item, {'$set': item}, upsert=True):
# if mongo_collection.insert_one(item):
print('存储成功')
else:
print('存储失败') def get_douban(self, total_movie):
# 每页10条,start_page循环1次
for start_page in range(0, total_movie, 10):
self.get_content(start_page) if __name__ == '__main__':
douban = Douban()
douban.get_douban(10)
爬虫数据使用MongDB保存时自动过滤重复数据的更多相关文章
- Intellij IDEA 代码格式化/保存时自动格式化
这里介绍使用google style 一.安装插件 1.settings -> plugins 选择 Browse repositories… 2.搜索google-java-format 和 ...
- vscode代码保存时自动格式化成ESLint风格(支持VUE)
一.问题 vscode的默认的代码格式化ctrl+shift+f 无法通过eslint的代码风格检查是一个非常蛋疼的问题 同样在进行vue项目开发的时候,使用eslint代码风格检查是没啥问题的,但是 ...
- 设置Myeclipse中的代码格式化、注释模板及保存时自动格式化
1:设置注释的模板: 下载此模板: codetemplates.xml 搜索Dangzhang,将其改为你自己的姓名,保存 打开eclipse/myeclipse选择 window-->Pre ...
- vscode 代码保存时自动格式化成 ESLint 风格
vscode 的默认的代码格式化 alt+shift+f (windows) 无法通过 eslint 的代码风格检查,,, 比如: 4个空格和2个空格(ESLint) 字符串用单引号(ESLint) ...
- Myeclipse学习总结(3)——Myeclipse中的代码格式化、注释模板及保存时自动格式化
设置Myeclipse中的代码格式化.注释模板及保存时自动格式化 1:设置注释的模板: 下载此模板: codetemplates.xml This XML file does not appear ...
- 关于visocode 自动保存时自动添加分号问题
先下载插件: Vueter 打开设置的配置文件,写入一下代码: // //是否需要保存时自动格式化 "editor.formatOnSave": true, //使js 文件保存 ...
- vscode代码格式化快捷键及保存时自动格式化
一.实现vs code中代码格式化快捷键:[Shift]+[Alt]+ F 二.实现保存时自动代码格式化: 1)文件 ------.>[首选项]---------->[设置]: 2)搜索 ...
- scrapy过滤重复数据和增量爬取
原文链接 前言 这篇笔记基于上上篇笔记的---<scrapy电影天堂实战(二)创建爬虫项目>,而这篇又涉及redis,所以又先熟悉了下redis,记录了下<redis基础笔记> ...
- Elasticsearch去重查询/过滤重复数据(聚合)
带家好,我是马儿,这次来讲一下最近遇到的一个问题 我司某个环境的es中被导入了重复数据,导致查询的时候会出现一些重复数据,所以要我们几个开发想一些解决方案,我们聊了聊,相出了下面一些方案: 1.从源头 ...
随机推荐
- JavaScript的代码库
JavaScript的代码库 本文主要是汇集了一些JavaScript中一些经常使用代码.方便以后查找和复用. javascript框架: <script language="java ...
- 安装 KB2844286 导致SharePoint 2010 XSLT web part 显示出现错误
上周末给Windows 打完补丁后,周一在通过From SharePoint的方式插入图片时,出现了如下错误: Unable to display this Web Part. To troubles ...
- hook 鼠标键盘消息实例分析
1.木马控制及通信方法包含:双管道,port重用.反弹技术.Hook技术,今天重点引用介绍一下hook的使用方法,hook信息后能够将结果发送到hacker邮箱等.实现攻击的目的. 转自:http:/ ...
- 更改printk打印级别【转】
本文转载自:http://blog.csdn.net/weed_hz/article/details/8949140 1.查看当前控制台的打印级别 cat /proc/sys/kernel/print ...
- mongodb 对内存的占用监控 ——mongostat,linux系统可用的内存是free + buffers + cached
刚开始使用mongodb的时候,不太注意mongodb的内存使用,但通过查资料发现mongodb对内存的占用是巨大的,在本地测试服务器中,8G的内存居然被占用了45%.汗呀. 本文就来剖析一下mong ...
- android sdk 更新失败问题解决办法
网上几乎都是这么说的 1.设置tools下的options,然后点击菜单packages下的reload 2.然后就会出现列表在点install进行安装 但是在更新时莫名其妙的也会出现错误 解决类似这 ...
- Django day08 多表操作 (四) 一对多, 多对多连续跨表查询
一对多 # 基于双下划线的一对多查询 # 查询出版社为上海出版社的所有图书 # ret = Publish.objects.filter(name='上海出版社').values('book__nam ...
- 如何对HTMLTestRunner 进行输出print 进行修改
在 HTMLTestRunner 模块中,在运行代码后,在输入的html页面值出现了特别简单的一个页面,那么现在如何将HTML页面中输出的更多print 在 HTMLTestRunner.py文件中查 ...
- NYOJ999 师傅又被妖怪抓走了
只记得当下的眼疼 , ok 各种数据也试了 , 就是 他娘的不对 , 我也是醉了 . 也是日了最野的狗 附上日了哮天犬的代码 , 这个题 先放放, 一段时间后再试试 , 明天开始状态压缩吧 .为期两天 ...
- python 13:数字列表统计方法(min(list)、max(list)、sum(list))
numbers = list(range(1,11)) print(numbers) print(min(numbers)) #获得列表最小值 print(max(numbers)) #获得列表最大值 ...