Python3 爬虫学习笔记 C11【数据储存系列 — MongoDB】
Python3 爬蟲學習筆記第十一章 —— 【數據儲存系列 — MongoDB】
文章目錄
- 【11.1】關于 MongoDB
- 【11.2】MongoDB 基本操作語句
- 【11.3】連接 MongoDB
- 【11.4】指定數據庫
- 【11.5】指定集合
- 【11.6】插入數據
- 【11.6】數據查詢
- 【11.7】數據計數
- 【11.8】數據排序
- 【11.9】數據偏移
- 【11.10】更新數據
- 【11.11】刪除數據
【11.1】關于 MongoDB
MongoDB 屬于非關系型數據庫,即 NoSQL(Not Only SQL),NoSQL 是基于鍵值對的,不需要經過 SQL 層的解析,數據之間沒有耦合性,性能極高,非關系型數據庫分為以下幾種:
- 鍵值存儲數據庫:Redis、Voldemort、Oracle BDB 等;
- 列存儲數據庫:Cassandra、HBase、Riak 等;
- 文檔型數據庫:CouchDB、MongoDB 等;
- 圖形數據庫:Neo4J、InfoGrid、Infinite Graph 等。
【11.2】MongoDB 基本操作語句
# 創建數據庫(如果數據庫不存在就創建數據庫, 存在就切換到指定的數據庫) use DATABASE_NAME# 查看所有數據庫 show dbs# 查看當前所在數據庫 db# 刪除當前數據庫 db.dropDatabase()# 刪除集合 db.COLLECTION_NAME.drop()# 創建集合 db.createCollection("COLLECTION_NAME")# 插入文檔 db.COLLECTION_NAME.insert(document) db.COLLECTION_NAME.save(document) # 更新文檔 db.COLLECTION_NAME.update()# 刪除文檔 db.COLLECTION_NAME.remove()# 查詢文檔 db.COLLECTION_NAME.find(query, projection)【11.3】連接 MongoDB
連接 MongoDB 需要導入 pymongo 庫,使用 MongoClient() 方法,向其傳入地址參數 host 和 端口參數 port 即可
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017)也可以直接傳入 MongoDB 的連接字符串:
import pymongoclient = pymongo.MongoClient('mongodb://localhost:27017/')【11.4】指定數據庫
使用以下語句皆可指定一個名為 spiders 的數據庫:
db = client.spiders db = client['spiders']【11.5】指定集合
MongoDB 的每個數據庫包含多個集合(collection),類似于關系型數據庫 MySQL 中的數據表,使用以下語句皆可指定一個名為 students 的集合:
collection = db.students collection = db['students']【11.6】插入數據
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students students = {'id': '17110105','name': 'TRHX','age': 20,'gender': 'male' } result = collection.insert(students) print(result)在 spiders 數據庫的 students 集合里,新建一條學生數據,該數據以字典形式表示,調用 collection 的 insert() 方法插入數據,在 MongoDB 中,每條數據都有一個_id 屬性來唯一標識。如果沒有顯式指明該屬性,MongoDB 會自動產生一個 ObjectId 類型的_id 屬性。insert() 方法會在執行后返回 _id 值,在 MongoDB 數據庫里面可以看到已經成功插入數據,輸出結果:
5d6f1a4b57b65e1547bb3c24進階操作:同時插入多條數據,以列表形式傳遞:
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students students1 = {'id': '17110105','name': 'TRHX','age': 20,'gender': 'male' } students2 = {'id': '17110106','name': 'AAAA','age': 22,'gender': 'male' } result = collection.insert([students1, students2]) print(result)輸出結果:
[ObjectId('5d6f2be3cd1721962218a709'), ObjectId('5d6f2be3cd1721962218a70a')]PyMongo 3.x 及以上版本中,推薦使用 insert_one() 和 insert_many() 方法來分別插入單條記錄和多條記錄,示例:
插入單條記錄
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students students = {'id': '17110105','name': 'TRHX','age': 20,'gender': 'male' } result = collection.insert_one(students) print(result) print(result.inserted_id)返回的是 InsertOneResult 對象,調用其 inserted_id 屬性獲取_id:
<pymongo.results.InsertOneResult object at 0x0000020ED91A5608> 5d6f73940fe700c5a7ac19f0插入多條記錄
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students students1 = {'id': '17110105','name': 'TRHX','age': 20,'gender': 'male' } students2 = {'id': '17110106','name': 'AAAA','age': 22,'gender': 'male' } result = collection.insert_many([students1, students2]) print(result) print(result.inserted_ids)返回的類型是 InsertManyResult,調用 inserted_ids 屬性可以獲取插入數據的_id 列表:
<pymongo.results.InsertManyResult object at 0x0000021698DD36C8> [ObjectId('5d6f68598fa881c69b2e0006'), ObjectId('5d6f68598fa881c69b2e0007')]【11.6】數據查詢
事先已經創建好 spiders 數據庫和 students 集合,包含以下數據:
_id:ObjectId("5d6f95d40828142f1dc35fa5") id:"17110105" name:"TRHX" age:20 gender:"male"_id:ObjectId("5d6f95d40828142f1dc35fa6") id:"17110106" name:"AAA" age:20 gender:"male"_id:ObjectId("5d6f95d40828142f1dc35fa7") id:"17110107" name:"BBB" age:19 gender:"female"_id:ObjectId("5d6f95d40828142f1dc35fa8") id:"17110108" name:"CCC" age:22 gender:"male"查詢方法一:利用 find_one() 或 find() 方法進行查詢, find_one() 查詢得到的是單個結果,find() 則返回一個生成器對象
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students result = collection.find_one({'name': 'TRHX'}) print(result)查詢 name 為 TRHX 的數據,返回一個字典類型:
{'_id': ObjectId('5d6f95d40828142f1dc35fa5'), 'id': '17110105', 'name': 'TRHX', 'age': 20, 'gender': 'male'}查詢方法二:根據 ObjectId 查詢,查詢時需要使用 bson 庫里面的 objectid:
import pymongo from bson.objectid import ObjectIdclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students result = collection.find_one({'_id': ObjectId('5d6f95d40828142f1dc35fa7')}) print(result)查詢結果:
{'_id': ObjectId('5d6f95d40828142f1dc35fa7'), 'id': '17110107', 'name': 'BBB', 'age': 19, 'gender': 'female'}使用 find() 方法查詢多條數據:
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students results = collection.find({'gender': 'male'}) print(results) for result in results:print(result)find() 方法返回一個生成器對象,遍歷得到所有數據,每條數據都是字典類型:
<pymongo.cursor.Cursor object at 0x00000191F69AAA90> {'_id': ObjectId('5d6f95d40828142f1dc35fa5'), 'id': '17110105', 'name': 'TRHX', 'age': 20, 'gender': 'male'} {'_id': ObjectId('5d6f95d40828142f1dc35fa6'), 'id': '17110106', 'name': 'AAA', 'age': 20, 'gender': 'male'} {'_id': ObjectId('5d6f95d40828142f1dc35fa8'), 'id': '17110108', 'name': 'CCC', 'age': 22, 'gender': 'male'}在查詢條件中加入比較符號進行查詢,以下代碼實現了年齡大于等于20的數據查詢:
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students results = collection.find({'age': {'$gte': 20}}) for result in results:print(result)符號 $gte 表示大于等于,查詢結果如下:
{'_id': ObjectId('5d6f95d40828142f1dc35fa5'), 'id': '17110105', 'name': 'TRHX', 'age': 20, 'gender': 'male'} {'_id': ObjectId('5d6f95d40828142f1dc35fa6'), 'id': '17110106', 'name': 'AAA', 'age': 20, 'gender': 'male'} {'_id': ObjectId('5d6f95d40828142f1dc35fa8'), 'id': '17110108', 'name': 'CCC', 'age': 22, 'gender': 'male'} 附表:各種比較符號| $lt | 小于 | {‘age’: {’$lt’: 20}} |
| $gt | 大于 | {‘age’: {’$gt’: 20}} |
| $lte | 小于等于 | {‘age’: {’$lte’: 20}} |
| $gte | 大于等于 | {‘age’: {’$gte’: 20}} |
| $ne | 不等于 | {‘age’: {’$ne’: 20}} |
| $in | 在范圍內 | {‘age’: {’$in’: [20, 23]}} |
| $nin | 不在范圍內 | {‘age’: {’$nin’: [20, 23]}} |
在查詢條件中加入功能符號進行查詢,以下代碼用正則匹配實現了對名字以 T 開頭的學生數據的查詢:
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students results = collection.find({'name': {'$regex': '^T.*'}}) for result in results:print(result)查詢結果:
{'_id': ObjectId('5d6f95d40828142f1dc35fa5'), 'id': '17110105', 'name': 'TRHX', 'age': 20, 'gender': 'male'} 附表:各種功能符號| $regex | 匹配正則表達式 | {‘name’: {’$regex’: ‘^T.*’}} | name 以 T 開頭 |
| $exists | 屬性是否存在 | {‘name’: {’$exists’: True}} | name 屬性存在 |
| $type | 類型判斷 | {‘age’: {’$type’: ‘int’}} | age 的類型為 int |
| $mod | 數字模操作 | {‘age’: {’$mod’: [5, 0]}} | 年齡模 5 余 0 |
| $text | 文本查詢 | {‘KaTeX parse error: Expected '}', got 'EOF' at end of input: text': {'search’: ‘Mike’}} | text 類型的屬性中包含 Mike 字符串 |
| $where | 高級條件查詢 | {’$where’: ‘obj.fans_count == obj.follows_count’} | 自身粉絲數等于關注數 |
其他操作:https://docs.mongodb.com/manual/reference/operator/query/
【11.7】數據計數
調用 count() 方法可以統計查詢結果有多少條數據,輸出結果為一個整數:
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students result = collection.find({'name': {'$regex': '^T.*'}}).count() print(result)【11.8】數據排序
調用 sort() 方法,向其傳入排序的字段及升降序標志即可完成排序:
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students ascending = collection.find().sort('name', pymongo.ASCENDING) descending = collection.find().sort('name', pymongo.DESCENDING) print('升序排列:', [result['name'] for result in ascending]) print('降序排列:', [result['name'] for result in descending])輸出結果:
升序排列: ['AAA', 'BBB', 'CCC', 'TRHX'] 降序排列: ['TRHX', 'CCC', 'BBB', 'AAA']【11.9】數據偏移
利用 skip() 方法偏移幾個位置,就可以跳過前幾條數據,獲取偏移量之后的幾個數據;利用 limit() 方法指定獲取前幾條數據:
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students ascending = collection.find().sort('name', pymongo.ASCENDING).skip(1) descending = collection.find().sort('name', pymongo.DESCENDING).limit(2) print('升序排列(偏移量為1,獲取后三條數據):', [result['name'] for result in ascending]) print('降序排列(限制獲取前兩條數據):', [result['name'] for result in descending])輸出結果:
升序排列(偏移量為1,獲取后三條數據): ['BBB', 'CCC', 'TRHX'] 降序排列(限制獲取前兩條數據): ['TRHX', 'CCC']【11.10】更新數據
使用 update() 方法,指定更新的條件和更新后的數據即可:
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students condition = {'name': 'TRHX'} student = collection.find_one(condition) student['age'] = 18 result = collection.update(condition, student) print(result)該代碼將 name 為 TRHX 的 age 改為了 18,返回結果仍然是字典形式,ok 代表執行成功,nModified 代表影響的數據條數:
{'n': 1, 'nModified': 1, 'ok': 1.0, 'updatedExisting': True}進階操作:使用 $set 操作符對數據進行更新,指定更新的條件和更新后的數據即可,這樣做的好處是:只更新指定的 student 字典內存在的字段,如果原先還有其他字段,則不會更新,也不會刪除;如果不用 $set ,則會把之前的數據全部用 student 字典替換,如果原本存在其他字段,則會被刪除
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students condition = {'name': 'TRHX'} student = collection.find_one(condition) student['age'] = 18 result = collection.update(condition, {'$set': student}) print(result)和插入數據的 insert() 方法一樣,在 PyMongo 3.x 版本里,推薦使用 update_one() 和 update_many() 方法
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students condition = {'name': 'TRHX'} student = collection.find_one(condition) student['age'] = 19 result = collection.update_one(condition, {'$set': student}) print(result) print(result.matched_count, result.modified_count)注意:update_one() 方法不能直接傳入修改后的字典,只能使用 {'$set': student} 的形式傳入,可以調用 matched_count 和 modified_count 屬性,獲取匹配的數據條數和影響的數據條數:
<pymongo.results.UpdateResult object at 0x00000235A1684508> 1 1使用update_many() 方法可以將所有符合條件的數據都更新:
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students condition = {'age': {'$gt': 18}} result = collection.update_many(condition, {'$set': {'age': 25}}) print(result) print(result.matched_count, result.modified_count)匹配所有年齡大于 18 的數據,更新條件為將這些所有滿足條件的年齡都設置成 25,輸出結果如下:
<pymongo.results.UpdateResult object at 0x00000285CECC45C8> 4 4【11.11】刪除數據
調用 remove() 方法并指定刪除的條件,此時符合條件的所有數據均會被刪除
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students result = collection.remove({'name': 'CCC'}) print(result)輸出結果:
{'n': 1, 'ok': 1.0}同樣的,在 PyMongo 3.x 版本里,推薦使用 delete_one() 和 delete_many() 方法
import pymongoclient = pymongo.MongoClient(host='localhost', port=27017) db = client.spiders collection = db.students result = collection.delete_one({'name': 'AAA'}) print(result) print(result.deleted_count) result = collection.delete_many({'gender': 'female'}) print(result.deleted_count)調用 deleted_count 屬性可以獲取刪除的數據條數,輸出結果:
<pymongo.results.DeleteResult object at 0x0000024441B245C8> 1 1PyMongo 官方文檔:http://api.mongodb.com/python/current/api/pymongo/collection.html
總結
以上是生活随笔為你收集整理的Python3 爬虫学习笔记 C11【数据储存系列 — MongoDB】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 招行汽车分期申请条件 招行汽车分期为何被
- 下一篇: Python 数据分析三剑客之 Pand