python mongo存在插入不存在更新,同时指定如果不存在才插入的字段
python爬虫的任务数据操作的小技巧
好久没写公众号了,最近太忙了,这里就不多说了。直接根据需求上代码,我想这个应该是大家比较喜欢的,
需求
爬取某网站的项目列表页,获取其url,标题等信息,作为后续爬取详情页的任务url。
先上代码
代码
# -*- coding: utf-8 -*-
# @Time : 2019-11-08 14:04
# @Author : cxa
# @File : motor_helper.py
# @Software: PyCharm
import asyncio
import datetime
from loguru import logger
from motor.motor_asyncio import AsyncIOMotorClient
from collections import Iterable
try:
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
except ImportError:
pass
db_configs = {
'host': '127.0.0.1',
'port': '27017',
'db_name': 'mafengwo',
'user': ''
}
class MotorOperation:
def __init__(self):
self.__dict__.update(**db_configs)
if self.user:
self.motor_uri = f"mongodb://{self.user}:{self.passwd}@{self.host}:{self.port}/{self.db_name}?authSource={self.db_name}"
else:
self.motor_uri = f"mongodb://{self.host}:{self.port}/{self.db_name}"
self.client = AsyncIOMotorClient(self.motor_uri)
self.mb = self.client[self.db_name]
async def save_data_with_status(self, items, col="seed_data"):
for item in items:
data = dict()
data["update_time"] = datetime.datetime.now()
data["status"] = 0 # 0初始
data.update(item)
print("data", data)
await self.mb[col].update_one({
"url": item.get("url")},
{'$set': data, '$setOnInsert': {'create_time': datetime.datetime.now()}},
upsert=True)
async def add_index(self, col="seed_data"):
# 添加索引
await self.mb[col].create_index('url')
因为我的爬虫是异步网络模块aiohttp写的,所以选择了pymongo的异步版本motor进行操作。
异步代码的基本属性就是async/await成对的出现,如果把上面的await和async去掉,就是类似pymongo的写法了,这里异步不是重点,重点是我们怎么处理每条数据。
这里除了网页的url,标题等信息,我需要附加3个字段。分别是create_time, status,update_time。
这三个字段分别代表,数据插入数据,状态和更新时间。
那么我为什么添加三个字段呢?
首先,我们需要判断每次的任务数据是否存在,我这里的情况是存在就更新不存在就插入,那么我就需要一个查询条件,作为更新的条件,很显然这里可以使用任务的url作为唯一条件(你还可以使用url+标题做个md5然后保存)。好了查询条件确定,
下面说create_time这个比较好理解就是数据插入时间,关键是为什么还要一个update_time,这个的话和status字段有一定的关系。 画重点:这个status作为后续爬虫进行爬取的一个标志用。目前这个status有4个值,0-4,我这是这样定义的,
0:初始状态 1:抓取中的任务 2:抓取成功 3:抓取失败 4:抓取成功但是没有匹配到任务。
后面随着任务的爬取,状态也是不断变化的,同时我们需要更新update_time为最新的时间。这个目前的话是体现不出来什么作用,它的使用场景是,重复任务的抓取,比如今天我抓取了任务列表里的url1,url2,第二天的时候我如果再抓到,为了区分是抓取失败还是抓取成功,我们根据create_time和update_time就可以进行推断了,如果两者相同而且是当前的日期说明刚抓的,如果update_time的日期比create_time新可以说明,抓到了重复的任务。关于字段的设计就啰嗦这么写。
下面是实现,我们可以通过update_one方法,对数据作存在或者插入操作,因为url作为查询条件,后面量大的话就最好添加一个索引。也就是上面的 add_index方法。
好了最好说插入更新的具体代码
需要注意的是
{'$set': data, '$setOnInsert': {'create_time': datetime.datetime.now()}}
$setOnInsert里面使用的字段是数据不存在的时候才插入的,存在就不动了,只插入$set里面指定的。
另外$setOnInsert里面使用的字段不能在$set里面再次出现
upsert=True代表的是不存在就插入。
大概就这么多,不明白的可以给我留言,或者添加微信进群交流。
python mongo存在插入不存在更新,同时指定如果不存在才插入的字段的更多相关文章
- Python Mongo操作
# -*- coding: utf-8 -*- ''' Python Mongo操作Demo Done: ''' from pymongo import MongoClient conn = None ...
- Python之路,Day25-----暂无正在更新中
Python之路,Day25-----暂无正在更新中
- Python之路,Day26-----暂无正在更新中
Python之路,Day26-----暂无正在更新中
- Python之路,Day23-----暂无正在更新中
Python之路,Day23-----暂无正在更新中
- Python之路,Day13-----暂无正在更新中
Python之路,Day13-----暂无正在更新中
- MySQL 避免重复数据的批量插入与批量更新
[转发] 导读 我们在向数据库里批量插入数据的时候,会遇到要将原有主键或者unique索引所在记录更新的情况,而如果没有主键或者unique索引冲突的时候,直接执行插入操作. 这种情况下,有三种方式执 ...
- spring data jpa开启批量插入、批量更新
spring data jpa开启批量插入.批量更新 原文链接:https://www.cnblogs.com/blog5277/p/10661096.html 原文作者:博客园--曲高终和寡 *** ...
- MySql快速插入以及批量更新
MySql快速插入以及批量更新 插入: MySql提供了可以一次插入多条数据的用法: [sql] INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6), ...
- mysql主键重复,不抱错,只更新的骚操作 (如果没有插入,如果有更新)
平时我们在设计数据库表的时候总会设计 unique 或者 给表加上 primary key 的限制条件. 此时 插入数据的时候 ,经常会有这样的情况: 我们想向数据库插入一条记录: 若数据表中存在以 ...
随机推荐
- android 给ImageView设置路径
ImageView是Android程序中经常用到的组件,它将一个图片显示到屏幕上. 在UI xml定义一个ImageView如下: public void onCreate(Bundle savedI ...
- c#读写apk的 comment
写入: ZipFile zipFile = new ZipFile("C:\\Users\\Administrator\\Desktop\\2.apk"); zipFile.Beg ...
- https小结
目录: 1.什么是https 2.https实现过程描述(https和证书小结) 3.(在客户端)https抓包解密 4.wireshark分析https数据包解密前后的特点 正文 1.什么是http ...
- /sys 和 /dev 区别
参考:What's the “/sys” directory for? Directory - /sys in linux 前言 各种Linux发行版下面似乎都有/sys目录,tree查看下面内容,会 ...
- MySQL事件自动kill运行时间超时的SQL
delimiter $create event my_long_running_trx_monitoron schedule every 1 minutestarts '2015-09-15 11:0 ...
- 如何设置CentOS 7获取动态IP和静态IP
自动获取动态IP地址 1.输入“ip addr”并按回车键确定,发现无法获取IP(CentOS 7默认没有ifconfig命令),记录下网卡名称(本例中为ens33). 2.输入“cd /etc/sy ...
- Machine learning system design---Error analysis
Error analysis--让我们系统的去判断我们接下来要做什么,而不是随机的,凭直觉地选择一个去做 我们在设计机器学习应用时,刚开始使用简单(简单的features)的算法来很快的完成它,它可能 ...
- MySQL复制介绍及搭建
MySQL复制介绍 MySQL复制就是一台MySQL服务器(slave)从另一台MySQL服务器(master)进行日志的复制然后再解析日志并应用到自身,类似Oracle中的Data Guard. M ...
- 火狐谷歌webdriver驱动地址
ChormeDrive下载 打开百度搜索Chromedriver官网下载,点击进入这个页面,链接为:http://npm.taobao.org/mirrors/chromedriver/2.41/ ...
- 为什么要使用ConcurrentHashMap
好久没写过技术性文章了,还是要坚持下去.掌握的知识,能写出来或者是讲给别人听才是真正的掌握了知识,如果不善于给别人讲,实际上还是没有真正掌握相关的知识,挑个简单的写吧. 面试的时候经常会被问到hash ...