Web crawler with Python - 05.是時候聊聊存儲問題了(轉(zhuǎn))

作者:xlzd

鏈接:https://zhuanlan.zhihu.com/p/20432575

來源:知乎

著作權(quán)歸作者所有呢灶。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

到目前為止彻亲,我們已經(jīng)可以編寫一些反爬蟲機制比較薄弱的網(wǎng)站爬蟲了堕担。不過,到上一篇博客結(jié)束座掘,我們抓到的數(shù)據(jù)依然還是存儲在文本文件中递惋。如此會存在一些不方便,比如不方便數(shù)據(jù)查找溢陪、刪除萍虽、更新,可能在第二次抓取的時候重復(fù)存儲等形真。這里杉编,介紹一下用數(shù)據(jù)庫存儲爬蟲數(shù)據(jù)。

由于爬蟲數(shù)據(jù)的結(jié)構(gòu)變化可能比較頻繁(不同時期網(wǎng)頁展示內(nèi)容可能豐富程度不一樣)咆霜,傳統(tǒng)的SQL型數(shù)據(jù)庫用來存儲的話會比較麻煩邓馒,所以我們更多的是使用NoSQL數(shù)據(jù)庫,這里以MongoDB為例蛾坯。

在數(shù)據(jù)抓取的過程中光酣,我們就應(yīng)該考慮好數(shù)據(jù)的表現(xiàn)形式。在大多數(shù)情況下脉课,爬蟲抓到的數(shù)據(jù)為以下兩種形式之一:

JSON文檔形式(如前一篇的拉勾招聘信息)挂疆,這種格式適用于絕大多數(shù)我們需要文本內(nèi)容的情況,我們將自己需要的數(shù)據(jù)的單條記錄表示為一批自定義key對應(yīng)網(wǎng)頁中特定value的k-v pair下翎,或者這樣的嵌套關(guān)系缤言。

文件形式,這種格式適用于抓取圖片資源视事、文檔資源等在瀏覽器端表現(xiàn)為二進制數(shù)據(jù)或需要下載的鏈接里面的數(shù)據(jù)胆萧。

首先介紹第一種格式吧。以上一篇博客的拉勾網(wǎng)為例,我們最后抓取到的數(shù)據(jù)跌穗,其實最后可以表達為以下形式(這里為了舉例只是展示少量字段):

{"jobTitle":"Python工程師","companyName":"奇虎360科技有限公司","salary":"20k-35k","city":"北京","workYear":"3-5年","positionId":1234566,}

上面關(guān)于JSON格式的描述的最后一句有點繞订晌,具體點的一個例子就是,比如我們抓取某個關(guān)鍵字對應(yīng)的百度搜索結(jié)果蚌吸,那么锈拨,我們得到的數(shù)據(jù)是這樣的(它不只是一個簡單的字符串關(guān)系的kv對,而是value也可能是一個object羹唠,如list或者dict):

{"keyword":"這是我們搜索的關(guān)鍵字","resultCount":"百度搜到了多少條信息","items":[# 我們搜到的信息的集合{# 單條信息"title":"標題","abstract":"信息摘要","releaseTime":"這條信息發(fā)布的時間","url":"這條信息的鏈接",},...],}

那么奕枢,對于上面拉勾招聘的數(shù)據(jù),我們能夠肯定的是佩微,這個招聘的id("positionId"字段)一定不會重復(fù)缝彬,于是,我們在將其存儲到數(shù)據(jù)庫的過程中哺眯,可以用positionId字段來唯一確定一條招聘信息谷浅,也即是主鍵。對應(yīng)到Python代碼奶卓,存儲到MongoDB的代碼示例如下:

importdatetimefrompymongoimportMongoClientMONGO_CONN=MongoClient(host,port)# MongoClient是線程安全的且內(nèi)部維護了一個連接池一疯,所以全局使用一個即可defsave(data):# data 表示需要存儲的單挑記錄(如上面的json,在Python中表現(xiàn)形式為dict)data['_id']=data['positionId']# 理由已經(jīng)解釋data['updateTime']=datetime.datetime.now()# 我們最好記錄下更新的時間# 其中夺姑,database墩邀、collection為你的數(shù)據(jù)庫及集合名稱MONGO_CONN['database']['collection'].update_one(filter={'_id':data['_id']},update={'$set':data},upsert=True)

我們可以通過如上方式將之前存儲到文件的代碼修改為存儲到數(shù)據(jù)庫中。pymongo是一個第三方庫瑟幕,所以你依然需要通過"pip install pymongo"來安裝它磕蒲。pymongo有很多操作MongoDB的API接口,這里不做過多講解只盹,你可以閱讀它的文檔或者在遇到問題的使用通過Google來解決辣往。

對于這樣的內(nèi)容,我們的抓取及存儲方式大概可以概括為:

選擇合適的格式保存

按照一定的規(guī)則確定不會重復(fù)保存兩條一樣的數(shù)據(jù)到庫中

寫爬蟲殖卑,并將存數(shù)據(jù)的接口實現(xiàn)為數(shù)據(jù)庫存儲方式

那么站削,對于存儲為文件的數(shù)據(jù)抓取,我們怎么做會更好一點呢孵稽?

其實還是要分情況考慮問題许起。如果你只是想簡單的抓取一批美女圖片(不管你想要健康或者是不健康的^_^),那么直接下載二進制流之后隨便取個名字存儲就好了菩鲜,比如隨機一串字符园细,或者使用文件內(nèi)容的數(shù)據(jù)摘要(MD5,sha1, ...),又或者是一個uuid接校,只要能確定不重復(fù)就夠了猛频,然后你就可以色瞇瞇地盯著這些圖片***了。

另一種情況下,比如這個文件是與一些如上所述的JSON數(shù)據(jù)掛鉤的鹿寻,比如說上面拉勾招聘的公司logo圖睦柴,這時候怎么考慮存儲問題更好呢?

這種情況下毡熏,我們要考慮到兩個問題:

不要重復(fù)存儲

可以方便地找回文件及其表示的含義

要達到這樣的目的坦敌,我們可以這樣:在得到文件的內(nèi)容后(一般為"requests.get('url').content"的值),我們?nèi)∷恼鎯槲募╩d5重復(fù)概率比較大痢法,建議使用sha1)狱窘,然后在MongoDB中維護一張collection——"fileMetaData",這個集合用于記錄對應(yīng)文件名(sha1)對應(yīng)的文件的content length疯暑、file type训柴、file path等信息哑舒。在招聘信息里增加一個字段“l(fā)ogo”妇拯,其值為fileMetaData中這條數(shù)據(jù)對應(yīng)的id即可(圖方便直接用文件的摘要做id)∠赐遥考慮到另一個問題是飞傀,如果文件數(shù)量較大(單個文件夾存儲數(shù)量有限)汉规,我們還可以將摘要的前幾位截取作為文件夾名。

小結(jié)

這里我們大概了解了如何通過數(shù)據(jù)庫保存我們爬到的數(shù)據(jù),以達到更方便檢索溉跃、更新、刪除的操作袖订。

有朋友私信說希望更新一部分關(guān)于反爬蟲機制的處理相關(guān)的內(nèi)容烂叔,這部分將會在后續(xù)更新,不過在這之前铲咨,先會有一篇關(guān)于較大數(shù)據(jù)量的抓取策略的探討躲胳。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市纤勒,隨后出現(xiàn)的幾起案子坯苹,更是在濱河造成了極大的恐慌,老刑警劉巖摇天,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粹湃,死亡現(xiàn)場離奇詭異,居然都是意外死亡泉坐,警方通過查閱死者的電腦和手機为鳄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腕让,“玉大人孤钦,你說我怎么就攤上這事。” “怎么了司训?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵构捡,是天一觀的道長。 經(jīng)常有香客問我壳猜,道長勾徽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任统扳,我火速辦了婚禮喘帚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘咒钟。我一直安慰自己吹由,他們只是感情好,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布朱嘴。 她就那樣靜靜地躺著倾鲫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪萍嬉。 梳的紋絲不亂的頭發(fā)上乌昔,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音壤追,去河邊找鬼磕道。 笑死,一個胖子當著我的面吹牛行冰,可吹牛的內(nèi)容都是我干的溺蕉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼悼做,長吁一口氣:“原來是場噩夢啊……” “哼疯特!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贿堰,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤辙芍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后羹与,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體故硅,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年纵搁,在試婚紗的時候發(fā)現(xiàn)自己被綠了吃衅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡腾誉,死狀恐怖徘层,靈堂內(nèi)的尸體忽然破棺而出峻呕,到底是詐尸還是另有隱情,我是刑警寧澤趣效,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布瘦癌,位于F島的核電站,受9級特大地震影響跷敬,放射性物質(zhì)發(fā)生泄漏讯私。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一西傀、第九天 我趴在偏房一處隱蔽的房頂上張望斤寇。 院中可真熱鬧,春花似錦拥褂、人聲如沸娘锁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽莫秆。三九已至,卻和暖如春尤慰,著一層夾襖步出監(jiān)牢的瞬間馏锡,已是汗流浹背雷蹂。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工伟端, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人匪煌。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓责蝠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親萎庭。 傳聞我的和親對象是個殘疾皇子霜医,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容