爬蟲
第七天
mongodb
mongo 客戶端連接
db
- db 顯示當前正在使用的數據庫
- show dbs 顯示所有數據
- use db(name) 使用指定數據庫
- db.dropDatabase() 刪除正在使用的數據庫
collection
- db.test 使用當前數據庫下面的test集合進行操作,如果沒有會自動創建
- show collecitons 顯示當前數據庫下的所有集合
- db.test.drop() 刪除當前的集合
pymongo
pip install pymongo
入門使用
from pymongo import MongoClient
# 創建一個客戶端鏈接服務器
client = MongoClient()
# 選擇要操作數據的數據庫和集合,返回一個可操作的集合對象
col = client['py']['test']
# 插入一條記錄,需要傳入一個字典即可
col.insert({"name": "py5"})
# 插入多條記錄,需要傳入一個列表,元素項爲字典
col.insert([{"name": "小王", "age": 18}, {"name": "小紅", "age": 20}])
在插入數據時,如果數據庫和集合不存在,會自動創建
刪除和更新
# 更新文檔,1.條件 2,更新內容 3.multi參數表示是否更新多條數據,默認false
col.update({"age": 18}, {"$set": {"name": "小明"}}, multi=False)
# 刪除文檔,1.條件 2,multi參數表示是否刪除多條滿足的文檔 默認True
col.remove({"age": 18}, multi=False)
查找
# # 遍歷取出集合中的每條數據
ret = col.find()
for x in ret:
print(x)
- find()返回了存儲結果集的遊標,可以通過迭代的方式依次取出結果
比較運算符
stu = client['py']['stu']
insert_list = [{'name': '段譽', 'hometown': '⼤理', 'age': 16, 'gender': False},
{'name': '洪七公', 'hometown': '華⼭', 'age': 18, 'gender': True},
{'name': '⻩蓉', 'hometown': '桃花島', 'age': 18, 'gender': False},
{'name': '華箏', 'hometown': '蒙古', 'age': 18, 'gender': False},
{'name': '郭靖', 'hometown': '蒙古', 'age': 20, 'gender': True},
{'name': '⻩藥師', 'hometown': '桃花島', 'age': 40, 'gender': True},
{'name': '段王爺', 'hometown': '⼤理', 'age': 45, 'gender': True}]
# 插入數據
stu.insert(insert_list)
# 查詢age=20的記錄
ret = stu.find({"age": 20})
# 查詢所有 age <= 20的記錄
ret = stu.find({"age": {"$lte": 20}})
# 查詢所有 age > 20的記錄
ret = stu.find({"age": {"$gt": 20}})
邏輯運算符
# 邏輯預算符,and關係
ret = stu.find({"age": 18, "gender": False})
# 邏輯預算符,or關係
ret = stu.find({"$or": [{"age": 18}, {"gender": False}]})
ret = stu.find({"$or": [{"age": {"$gte": 18}}, {"gender": False}]})
範圍運算符
# 範圍運算符 in
# ret = stu.find({"age": {"$in": [18, 20]}})
翻頁
# 翻頁 skip 跳過 limit 選中
ret = stu.find()
for x in ret:
print(x)
print("*" * 100)
ret = stu.find().skip(3).limit(2)
for x in ret:
print(x)
投影
# 投影,約束需要顯示的字段
# ret = stu.find({}, {"_id": 0, "name": 1, "hometown": 1})
排序
# 排序 1升序,-1降序
import pymongo
ret = stu.find().sort([("age", pymongo.ASCENDING), ("gender", pymongo.DESCENDING)])
統計個數
# 統計個數 count中只能計數
ret = stu.find({"age": {"$lt": 18}}).count()
print(ret)
去重
# 篩選數據並去重,返回的是一個去重後的列表
ret = stu.distinct("hometown", {"age": {"$gt": 20}})
for x in ret:
print(x)
管道
聚合(aggregate)是基於數據處理的聚合管道,每個文檔通過一個由多個階段(stage)組成的管道,可以對每個階段的管道進行分組、過濾等功能,然後經過一系列的處理,輸出相應的結果。
管道命令
$group
: 將集合中的⽂檔分組, 可⽤於統計結果$match
: 過濾數據, 只輸出符合條件的⽂檔$project
: 修改輸⼊⽂檔的結構, 如重命名、 增加、 刪除字段、 創建計算結果$sort
: 將輸⼊⽂檔排序後輸出$limit
: 限制聚合管道返回的⽂檔數$skip
: 跳過指定數量的⽂檔, 並返回餘下的⽂檔
管道表達式
-
$sum
: 計算總和, $sum:1 表示以⼀倍計數 -
$avg
: 計算平均值 -
$min
: 獲取最⼩值 -
$max
: 獲取最⼤值 -
$push
: 在結果⽂檔中插⼊值到⼀個數組中
語法:db.集合名稱.aggregate({管道:{表達式}})
# $group分組 "_id"分組的依據 $sum:1統計組內個數, $sum:$age 組內的年齡求和 $push 數據透視,組內元素放入一個列表中
ret = stu.aggregate(
[{"$group": {"_id": "$hometown", "count": {"$sum": 1}, "age": {"$sum": "$age"}, "name": {"$push": "$name"}}}])
# 多個字段進行分組
ret = stu.aggregate([{"$group": {"_id": {"性別": "$gender", "姓名": "$name"}}}])
ret = stu.aggregate([
{"$match": {"age": {"$gt": 20}}},
{"$group": {"_id": {"gender": "$gender", "hometown": "$hometown"}}},
{"$project": {"_id": 0, "性別": "$_id.gender", "故鄉": "$_id.hometown"}},
{"$group": {"_id": "$性別", "人數": {"$sum": 1}}}])
ret = stu.aggregate([{"$group": {"_id": "$hometown", "count": {"$sum": 1}}},
{"$sort": {"count": pymongo.ASCENDING}},
{"$skip": 1},
{"$limit": 2}])
索引
索引的作用?
- 加快查詢速度
- 進行數據的去重
# 設置索引,1.提升查找效率,2數據去重
stu.ensure_index([("name", pymongo.ASCENDING)], unique=True)
# 獲取索引,並美化打印
x = stu.index_information()
print(json.dumps(x, indent=2))
# 設置複合索引實現數據去重
stu.ensure_index([("name", pymongo.ASCENDING), ("age", pymongo.DESCENDING)])
爬蟲中,數據去重的一個重要手段就是:選擇合適數據字段,建立複合索引