數(shù)據(jù)庫緩存:
為 了避免磁盤緩存方案的 己知限制村视,下面我們會在現(xiàn)有數(shù)據(jù)庫系統(tǒng)之上創(chuàng)建緩存 吉挣。 爬取時稍味, 我們可能需要緩存大量數(shù)據(jù)井濒, 但又無須任何復(fù)雜的連接操作灶似, 因此我們將選用 NoSQL 數(shù)據(jù)庫, 這種數(shù)據(jù)庫 比傳統(tǒng)的關(guān)系型數(shù)據(jù)庫更易于擴展瑞你。在本節(jié)中 酪惭, 我們將會選用 目 前非常流行的 MongoDB 作為緩存數(shù)據(jù)庫。
NoSql是什么
NoSQL 全稱為 Not Only SQL者甲, 是一種相對較新的數(shù)據(jù)庫設(shè)計方式春感。 傳統(tǒng)
的關(guān)系模型使用 的是固定模式, 并將數(shù)據(jù)分割到各個表中 虏缸。 然而鲫懒, 對于大數(shù)
據(jù)集的情況, 數(shù)據(jù)量太大使其難 以存放在單一服務(wù)器中 刽辙, 此時就需要擴展到
多 臺服務(wù)器窥岩。 不過, 關(guān)系模型對于這種擴展的支持并不夠好宰缤, 因為在查詢多
個表時颂翼, 數(shù)據(jù)可能在不同的服務(wù)器中 。 相反慨灭, NoSQL 數(shù)據(jù)庫通常是無模式的朦乏,
從設(shè)計之初就考慮了跨服務(wù)器無縫分片 的 問題。 在 NoSQL 中 氧骤, 有多種方式可
以實現(xiàn)該 目 標(biāo)呻疹, 分別是列數(shù)據(jù)存儲 ( 如 HBase)、 鍵值對存儲 (如 Redis)语淘、 面
向文檔的數(shù)據(jù)庫 ( 如 MongoDB) 以及圖形數(shù)據(jù)庫 ( 如 Neo4j ) 诲宇。
windows安裝MongoDB:
下載之后一直點擊下一步安裝完成际歼,
配置環(huán)境變量 我的電腦-屬性-高級系統(tǒng)設(shè)置-環(huán)境變量-path路徑下添加mogodb路徑(D:\mongdb\bin)注意路徑與之前的需要用;分號間隔
在mongodb路徑下建立data文件夾
在cmd中輸入mongod --dbpath D:\mongdb\data 啟動
重開一個cmd然后輸入mongo 看是否鏈接成功
或者在瀏覽器輸入http://localhost:27017/ (27017是默認(rèn)端口)顯示如下則啟動成功
安裝pymongo python封裝庫
pip install pymongo
在python中使用MongoDB的默認(rèn)端口鏈接MongoDB
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
存取緩存數(shù)據(jù):
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
url = 'http://example.webscraping.com/view/united-kingdom-239'
html = 'f'
db = client.cache
db.webpage.insert({'url': url, 'html': html})
print db.webpage.find_one({'url': url})
db.webpage.insert({'url': url, 'html': html})
print db.webpage.find({'url': url}).count()
如果是想更新內(nèi)容則使用update將上面更改一下
new_html = '<html></html>'
db.webpage.update({'_id': url},{'$set':{'html' : new_html}}, upsert = True)
print db.webpage.find_one({'_id': url})
使用MongoDB實現(xiàn)緩存
from datetime import datetime, timedelta
from pymongo import MongoClient
from link_crawler import link_crawler
class MongoCache:
def __init__(self, client=None, expires=timedelta(days=30)):
self.client = MongoClient('localhost', 27017)
self.db = self.client.cache
self.db.webpage.create_index('timestamp', expireAfterSeconds=expires.total_seconds())
def __getitem__(self, url):
record = self.db.webpage.find_one({'_id': url})
if record:
return record['result']
else:
raise KeyError(url + 'does not exist')
def __setitem__(self, url, result):
record = {'result': result, 'timestamp': datetime.utcnow()}
self.db.webpage.update({'_id': url}, {'$set': record}, upsert=True)
if __name__ == '__main__':
link_crawler('http://example.webscraping.com/', '/(index|view)', cache=MongoCache())
總結(jié):
緩存己下載的網(wǎng)頁可以節(jié)省時間 , 并能最小化重新爬取網(wǎng)站所耗費的帶寬 姑蓝。 緩存的主要缺點是會占用磁盤空間 鹅心, 不過我們可 以使用壓縮的方式減少空間 占用 。 此外纺荧, 在類似 MongoDB 等現(xiàn)有數(shù)據(jù)庫的基礎(chǔ)之上創(chuàng)建緩存旭愧, 可以避免文件系統(tǒng)的各種限制。
學(xué)習(xí)《用Python寫網(wǎng)絡(luò)爬蟲》
相關(guān)源碼