最近寫爬蟲用到的是mongodb數據庫,部署在阿里云的服務器,下面簡單記錄一下用到的操作,已被后用。(關于mongodb的安裝配置參考其他資料,后續補充)
基本操作:
def find_data():
print("init mongo")
client = MongoClient(ip)
db = client[database]
db.authenticate(user, pwd)
c = db[collection]
# c.create_index("movieid", unique=True)
# 其余操作
client.close()
插入:
可以使用insert_one或者insert_many插入多條數據,但是我插入的數據經常會有重復,因此想到兩種解決方法。
以豆瓣電影的一條記錄來說:
首先建立唯一索引:
c.create_index("movieid", unique=True)
- 利用
try catch
來保證唯一插入,try catch
也可用于其他異常處理
try:
insert_one #說明有相同記錄
except e:
print(e)
- upsert命令:
collection.update_one({"movieid": movieid}, {"$set": item}, upsert=True)
上述用于更新一條記錄,不存在則插入。{"$set": item}
, 全部更新,也可選擇部分更新。
查找find操作
-
results = c.find().count()
用于記錄,find中可以加條件。
mark = "wish_count"
results = c.find({"subtype": "tv", mark: {"$gte": 10000, "$lte": 30000}}, {"_id": 0, "title": 1, "rate": 1, mark: 1}).sort([("rate", -1), (mark, -1)])
這條語句的意思是;根據subtype=“tv”
, mark
在10000~30000
之間進行查找,結果中不顯示_id
字段(find的第二個參數,0不顯示,1顯示), 顯示title
和rate
字段。
結果按照rate, mark的順序降序排列(1為升序)。
results = c.find({"title": {"$regex": "大明"}})
類似like操作,查找title包含大明的集合。results = c.find({"casts": {"$in": ["1", "2"]}})
查找集合中演員列表存在1, 2字段的集合。
組合操作:
pipeline = [
{"$match": {"subtype": "tv"}},
{"$unwind": "$casts"},
{"$group": {"_id": "$casts", "count": {"$sum": 1}, "avg": {"$avg": "$rate"}}},
{"$sort": {"avg": -1}},
# {"$match": {"count": {"$gte": 3, "$lte": 4}}}
{"$match": {"_id": "鹿晗"}}
]
results = c.aggregate(pipeline)
組合操作:
第一個match
和find
的第一個參數一樣,用于組合前篩選。
unwind
:展開,用于該字段是列表時,展開進行組合操作,不是列表可省略。
group
:_id
是必須字段,count
, avg
自定義字段, sum
, avg
分別是求和,求平均操作。
sort
關鍵字不在敘述。
后面match
用于組合后篩選, gte
是大于等于,lte
是小于等于字段。
綜上:這條操作的意思是:
對subtype=“tv”
的集合進行操作,展開casts
字段,對其進行組合,計算出現次數count
, 對集合的rate
求平均值。結果按照平均值排序,并篩選出count在3~4之間
的集合(_id=“鹿晗”)
。
后續用到再補充,具體其他操作請查看官方文檔。