準(zhǔn)備
安裝Mongodb數(shù)據(jù)庫
其實(shí)不是一定要使用MongoDB,大家完全可以使用MySQL或者Redis,全看大家喜好。這篇文章我們的例子是Mongodb,所以大家需要下載它。
在Windows中。由于MongoDB默認(rèn)的數(shù)據(jù)目錄為C:\data\db,建議大家直接在安裝的時(shí)候更改默認(rèn)路徑為C:\MongoDB.
然后創(chuàng)建如下目錄文件:
C:\data\log\mongod.log? //用于存儲(chǔ)數(shù)據(jù)庫的日志
C:\data\db??? //用于存儲(chǔ)數(shù)據(jù)庫數(shù)據(jù)
然后在C:\MongoDB文件夾下(安裝 Mongodb 路徑)創(chuàng)建配置文件mongod.cfg。并且在配置文件里寫入以下配置:

大家記住要打開文件后綴名,不然我們可能創(chuàng)建了一個(gè)mongod.cfg.txt文件。
最后我們需要打開管理員權(quán)限的 CMD 窗口,執(zhí)行如下命令,安裝數(shù)據(jù)庫成服務(wù):
"C:\mongodb\bin\mongod.exe"--config "C:\mongodb\mongod.cfg"--install
設(shè)置為服務(wù)后,需要在管理員權(quán)限打開的windows cmd窗口用服務(wù)的方式啟動(dòng)或停止MongoDB。
net start mongodb??? //啟動(dòng)mongodb服務(wù)
net stop mongodb???? //關(guān)閉mongodb服務(wù)
好了,安裝好Mongodb數(shù)據(jù)庫后,我們需要安裝PyMongo,它是MongoDB的Python接口開發(fā)包。
pip install pymongo
推薦下我自己創(chuàng)建的Python學(xué)習(xí)交流群960410445,這是Python學(xué)習(xí)交流的地方,不管你是小白還是大牛,小編都?xì)g迎,不定期分享干貨,包括我整理的一份適合零基礎(chǔ)學(xué)習(xí)Python的資料和入門教程。
開始
準(zhǔn)備完成后,我們就開始瀏覽拉勾網(wǎng)。我們可以發(fā)現(xiàn)拉勾網(wǎng)所有的招聘職位都在左側(cè)分類里。如圖:

我們先獲取首頁HTML文件:

然后我們打開開發(fā)者工具,找到招聘職業(yè)的位置。

大家還記得BeautifulSoup的CSS選擇器吧,我們直接使用.select()方法獲取標(biāo)簽信息。

輸出結(jié)果:
[<a class="curr"href="https://www.lagou.com/zhaopin/Java/"data-lg-tj-cid="idnull"data-lg-tj-id="4O00"data-lg-tj-no="0101">Java</a>, <a class="curr"href="https://www.lagou.com/zhaopin/C%2B%2B/"data-lg-tj-cid="idnull"data-lg-tj-id="4O00"data-lg-tj-no="0102">C++</a>, # ... 省略部分 https://www.lagou.com/zhaopin/fengxiankongzhizongjian/" data-lg-tj-cid="idnull" data-lg-tj-id="4U00" data-lg-tj-no="0404">風(fēng)控總監(jiān), https://www.lagou.com/zhaopin/zongcaifuzongcai/" data-lg-tj-cid="idnull" data-lg-tj-id="4U00" data-lg-tj-no="0405">副總裁]
260
獲取到所有職位標(biāo)簽的a標(biāo)簽后,我們只需要提取標(biāo)簽的href屬性和標(biāo)簽內(nèi)內(nèi)容,就可以獲得到職位的招聘鏈接和招聘職位的名稱了。我們準(zhǔn)備信息生成一個(gè)字典。方便我們后續(xù)程序的調(diào)用。

這里我們用zip函數(shù),同時(shí)迭代兩個(gè)list。生成一個(gè)鍵值對。
接下來我們可以隨意點(diǎn)擊一個(gè)職位分類,分析招聘頁面的信息。
分頁
我們首先來分析下網(wǎng)站頁數(shù)信息。經(jīng)過我的觀察,每個(gè)職位的招聘信息最多不超過 30 頁。也就是說,我們只要從第 1 頁循環(huán)到第 30 頁,就可以得到所有招聘信息了。但是也可以看到有的職位招聘信息,頁數(shù)并不到 30 頁。以下圖為例:

如果我們訪問頁面:https://www.lagou.com/zhaopin/Java/31/
也就是第 31 頁。我們會(huì)得到 404 頁面。所以我們需要在訪問到404頁面時(shí)進(jìn)行過濾。
ifresp.status_code ==404:
????pass
這樣我們就可以放心的 30 頁循環(huán)獲得每一頁招聘信息了。
我們的每一頁url使用format拼接出來:
link ='{}{}/'.format(url, str(pages))
獲取信息


獲取到全部信息后,我們同樣的把他們組成鍵值對字典。

組成字典的目的是方便我們將全部信息保存到數(shù)據(jù)庫。
保存數(shù)據(jù)
保存數(shù)據(jù)庫前我們需要配置數(shù)據(jù)庫信息:

這里我們導(dǎo)入了pymongo庫,并且與MongoDB建立連接,這里是默認(rèn)連接本地的MongoDB數(shù)據(jù)。創(chuàng)建并選擇一個(gè)數(shù)據(jù)庫lagou,并在這個(gè)數(shù)據(jù)庫中,創(chuàng)建一個(gè)table,即url_list。然后,我們進(jìn)行數(shù)據(jù)的保存:
ifurl_list.insert_one(data):
????print('保存數(shù)據(jù)庫成功', data)
如果保存成功,打印出成功信息。
多線程爬取
十萬多條數(shù)據(jù)是不是抓取的有點(diǎn)慢,有辦法,我們使用多進(jìn)程同時(shí)抓取。由于Python的歷史遺留問題,多線程在Python中始終是個(gè)美麗的夢。

我們把之前提取職位招聘信息的代碼,寫成一個(gè)函數(shù),方便我們調(diào)用。這里的parse_link()就是這個(gè)函數(shù),他就收職位的 url 和所有頁數(shù)為參數(shù)。我們get_alllink_data()函數(shù)里面使用for循環(huán) 30 頁的數(shù)據(jù)。然后這個(gè)作為主函數(shù)傳給多進(jìn)程內(nèi)部調(diào)用。

這里是一個(gè)pool進(jìn)程池,我們調(diào)用進(jìn)程池的map方法.
map(func, iterable[,chunksize=None])
多進(jìn)程Pool類中的map方法,與Python內(nèi)置的map函數(shù)用法行為基本一致。它會(huì)使進(jìn)程阻塞,直到返回結(jié)果。需要注意,雖然第二個(gè)參數(shù)是一個(gè)迭代器,但在實(shí)際使用中,必須在整個(gè)隊(duì)列都就緒后,程序才會(huì)運(yùn)行子進(jìn)程。join()
方法等待子進(jìn)程結(jié)束后再繼續(xù)往下運(yùn)行,通常用于進(jìn)程間的同步.
反爬蟲處理
如果大家就這樣整理完代碼,直接就開始抓取的話。相信在抓取的不久后就會(huì)出現(xiàn)程序中止不走了。我剛剛第一次中止后,我以為是網(wǎng)站限制了我的 ip。于是我做了如下改動(dòng)。
