溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

如何使用Python編寫(xiě)多線(xiàn)程爬蟲(chóng)抓取百度貼吧郵箱與手機(jī)號(hào)

發(fā)布時(shí)間:2021-10-28 16:57:03 來(lái)源:億速云 閱讀:157 作者:柒染 欄目:編程語(yǔ)言

本篇文章給大家分享的是有關(guān)如何使用Python編寫(xiě)多線(xiàn)程爬蟲(chóng)抓取百度貼吧郵箱與手機(jī)號(hào),小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話(huà)不多說(shuō),跟著小編一起來(lái)看看吧。

不知道大家過(guò)年都是怎么過(guò)的,反正欄主是在家睡了一天,醒來(lái)的時(shí)候登QQ發(fā)現(xiàn)有人找我要一份貼吧爬蟲(chóng)的源代碼,想起之前練手的時(shí)候?qū)戇^(guò)一個(gè)抓取百度貼吧發(fā)帖記錄中的郵箱與手機(jī)號(hào)的爬蟲(chóng),于是開(kāi)源分享給大家學(xué)習(xí)與參考。

需求分析:

本爬蟲(chóng)主要是對(duì)百度貼吧中各種帖子的內(nèi)容進(jìn)行抓取,并且分析帖子內(nèi)容將其中的手機(jī)號(hào)和郵箱地址抓取出來(lái)。主要流程在代碼注釋中有詳細(xì)解釋。

測(cè)試環(huán)境:

代碼在Windows7 64bit,python 2.7 64bit(安裝mysqldb擴(kuò)展)以及centos 6.5,python 2.7(帶mysqldb擴(kuò)展)環(huán)境下測(cè)試通過(guò)

如何使用Python編寫(xiě)多線(xiàn)程爬蟲(chóng)抓取百度貼吧郵箱與手機(jī)號(hào)

如何使用Python編寫(xiě)多線(xiàn)程爬蟲(chóng)抓取百度貼吧郵箱與手機(jī)號(hào)

環(huán)境準(zhǔn)備:

工欲善其事必先利其器,大家可以從截圖看出我的環(huán)境是Windows 7 + PyCharm。我的Python環(huán)境是Python 2.7  64bit。這是比較適合新手使用的開(kāi)發(fā)環(huán)境。然后我再建議大家安裝一個(gè)easy_install,聽(tīng)名字就知道這是一個(gè)安裝器,它是用來(lái)安裝一些擴(kuò)展包的,比如說(shuō)在python中如果我們要操作mysql數(shù)據(jù)庫(kù)的話(huà),python原生是不支持的,我們必須安裝mysqldb包來(lái)讓python可以操作mysql數(shù)據(jù)庫(kù),如果有easy_install的話(huà)我們只需要一行命令就可以快速安裝號(hào)mysqldb擴(kuò)展包,他就像php中的composer,centos中的yum,Ubuntu中的apt-get一樣方便。

相關(guān)工具可在我的github中找到:cw1997/python-tools,其中easy_install的安裝只需要在python命令行下運(yùn)行那個(gè)py腳本然后稍等片刻即可,他會(huì)自動(dòng)加入Windows的環(huán)境變量,在Windows命令行下如果輸入easy_install有回顯說(shuō)明安裝成功。

環(huán)境選擇的細(xì)節(jié)說(shuō)明:

至于電腦硬件當(dāng)然是越快越好,內(nèi)存起碼8G起步,因?yàn)榕老x(chóng)本身需要大量存儲(chǔ)和解析中間數(shù)據(jù),尤其是多線(xiàn)程爬蟲(chóng),在碰到抓取帶有分頁(yè)的列表和詳情頁(yè),并且抓取數(shù)據(jù)量很大的情況下使用queue隊(duì)列分配抓取任務(wù)會(huì)非常占內(nèi)存。包括有的時(shí)候我們抓取的數(shù)據(jù)是使用json,如果使用mongodbnosql數(shù)據(jù)庫(kù)存儲(chǔ),也會(huì)很占內(nèi)存。

網(wǎng)絡(luò)連接建議使用有線(xiàn)網(wǎng),因?yàn)槭忻嫔弦恍┝淤|(zhì)的無(wú)線(xiàn)路由器和普通的民用無(wú)線(xiàn)網(wǎng)卡在線(xiàn)程開(kāi)的比較大的情況下會(huì)出現(xiàn)間歇性斷網(wǎng)或者數(shù)據(jù)丟失,掉包等情況,這個(gè)我親有體會(huì)。

至于操作系統(tǒng)和python當(dāng)然肯定是選擇64位。如果你使用的是32位的操作系統(tǒng),那么無(wú)法使用大內(nèi)存。如果你使用的是32位的python,可能在小規(guī)模抓取數(shù)據(jù)的時(shí)候感覺(jué)不出有什么問(wèn)題,但是當(dāng)數(shù)據(jù)量變大的時(shí)候,比如說(shuō)某個(gè)列表,隊(duì)列,字典里面存儲(chǔ)了大量數(shù)據(jù),導(dǎo)致python的內(nèi)存占用超過(guò)2g的時(shí)候會(huì)報(bào)內(nèi)存溢出錯(cuò)誤。原因在我曾經(jīng)segmentfault上提過(guò)的問(wèn)題中依云的回答有解釋?zhuān)╦ava – python只要占用內(nèi)存達(dá)到1.9G之后httplib模塊就開(kāi)始報(bào)內(nèi)存溢出錯(cuò)誤 – SegmentFault)

如果你準(zhǔn)備使用mysql存儲(chǔ)數(shù)據(jù),建議使用mysql5.5以后的版本,因?yàn)閙ysql5.5版本支持json數(shù)據(jù)類(lèi)型,這樣的話(huà)可以?huà)仐塵ongodb了。(有人說(shuō)mysql會(huì)比mongodb穩(wěn)定一點(diǎn),這個(gè)我不確定。)

至于現(xiàn)在python都已經(jīng)出了3.x版本了,為什么我這里還使用的是python2.7?我個(gè)人選擇2.7版本的原因是自己當(dāng)初很早以前買(mǎi)的python核心編程這本書(shū)是第二版的,仍然以2.7為示例版本。并且目前網(wǎng)上仍然有大量的教程資料是以2.7為版本講解,2.7在某些方面與3.x還是有很大差別,如果我們沒(méi)有學(xué)過(guò)2.7,可能對(duì)于一些細(xì)微的語(yǔ)法差別不是很懂會(huì)導(dǎo)致我們理解上出現(xiàn)偏差,或者看不懂demo代碼。而且現(xiàn)在還是有部分依賴(lài)包只兼容2.7版本。我的建議是如果你是準(zhǔn)備急著學(xué)python然后去公司工作,并且公司沒(méi)有老代碼需要維護(hù),那么可以考慮直接上手3.x,如果你有比較充裕的時(shí)間,并且沒(méi)有很系統(tǒng)的大牛帶,只能依靠網(wǎng)上零零散散的博客文章來(lái)學(xué)習(xí),那么還是先學(xué)2.7在學(xué)3.x,畢竟學(xué)會(huì)了2.7之后3.x上手也很快。

多線(xiàn)程爬蟲(chóng)涉及到的知識(shí)點(diǎn):

其實(shí)對(duì)于任何軟件項(xiàng)目而言,我們凡是想知道編寫(xiě)這個(gè)項(xiàng)目需要什么知識(shí)點(diǎn),我們都可以觀察一下這個(gè)項(xiàng)目的主要入口文件都導(dǎo)入了哪些包。

如何使用Python編寫(xiě)多線(xiàn)程爬蟲(chóng)抓取百度貼吧郵箱與手機(jī)號(hào)

現(xiàn)在來(lái)看一下我們這個(gè)項(xiàng)目,作為一個(gè)剛接觸python的人,可能有一些包幾乎都沒(méi)有用過(guò),那么我們?cè)诒拘」?jié)就來(lái)簡(jiǎn)單的說(shuō)說(shuō)這些包起什么作用,要掌握他們分別會(huì)涉及到什么知識(shí)點(diǎn),這些知識(shí)點(diǎn)的關(guān)鍵詞是什么。這篇文章并不會(huì)花費(fèi)長(zhǎng)篇大論來(lái)從基礎(chǔ)講起,因此我們要學(xué)會(huì)善用百度,搜索這些知識(shí)點(diǎn)的關(guān)鍵詞來(lái)自學(xué)。下面就來(lái)一一分析一下這些知識(shí)點(diǎn)。

HTTP協(xié)議:

我們的爬蟲(chóng)抓取數(shù)據(jù)本質(zhì)上就是不停的發(fā)起http請(qǐng)求,獲取http響應(yīng),將其存入我們的電腦中。了解http協(xié)議有助于我們?cè)谧ト?shù)據(jù)的時(shí)候?qū)σ恍┠軌蚣铀僮ト∷俣鹊膮?shù)能夠精準(zhǔn)的控制,比如說(shuō)keep-alive等。

threading模塊(多線(xiàn)程):

我們平時(shí)編寫(xiě)的程序都是單線(xiàn)程程序,我們寫(xiě)的代碼都在主線(xiàn)程里面運(yùn)行,這個(gè)主線(xiàn)程又運(yùn)行在python進(jìn)程中。關(guān)于線(xiàn)程和進(jìn)程的解釋可以參考阮一峰的博客:進(jìn)程與線(xiàn)程的一個(gè)簡(jiǎn)單解釋 – 阮一峰的網(wǎng)絡(luò)日志

在python中實(shí)現(xiàn)多線(xiàn)程是通過(guò)一個(gè)名字叫做threading的模塊來(lái)實(shí)現(xiàn)。之前還有thread模塊,但是threading對(duì)于線(xiàn)程的控制更強(qiáng),因此我們后來(lái)都改用threading來(lái)實(shí)現(xiàn)多線(xiàn)程編程了。

關(guān)于threading多線(xiàn)程的一些用法,我覺(jué)得這篇文章不錯(cuò):[python] 專(zhuān)題八.多線(xiàn)程編程之thread和threading 大家可以參考參考。

簡(jiǎn)單來(lái)說(shuō),使用threading模塊編寫(xiě)多線(xiàn)程程序,就是先自己定義一個(gè)類(lèi),然后這個(gè)類(lèi)要繼承threading.Thread,并且把每個(gè)線(xiàn)程要做的工作代碼寫(xiě)到一個(gè)類(lèi)的run方法中,當(dāng)然如果線(xiàn)程本身在創(chuàng)建的時(shí)候如果要做一些初始化工作,那么就要在他的__init__方法中編寫(xiě)好初始化工作所要執(zhí)行的代碼,這個(gè)方法就像php,java中的構(gòu)造方法一樣。

這里還要額外講的一點(diǎn)就是線(xiàn)程安全這個(gè)概念。通常情況下我們單線(xiàn)程情況下每個(gè)時(shí)刻只有一個(gè)線(xiàn)程在對(duì)資源(文件,變量)操作,所以不可能會(huì)出現(xiàn)沖突。但是當(dāng)多線(xiàn)程的情況下,可能會(huì)出現(xiàn)同一個(gè)時(shí)刻兩個(gè)線(xiàn)程在操作同一個(gè)資源,導(dǎo)致資源損壞,所以我們需要一種機(jī)制來(lái)解決這種沖突帶來(lái)的破壞,通常有加鎖等操作,比如說(shuō)mysql數(shù)據(jù)庫(kù)的innodb表引擎有行級(jí)鎖等,文件操作有讀取鎖等等,這些都是他們的程序底層幫我們完成了。所以我們通常只要知道那些操作,或者那些程序?qū)τ诰€(xiàn)程安全問(wèn)題做了處理,然后就可以在多線(xiàn)程編程中去使用它們了。而這種考慮到線(xiàn)程安全問(wèn)題的程序一般就叫做“線(xiàn)程安全版本”,比如說(shuō)php就有TS版本,這個(gè)TS就是Thread  Safety線(xiàn)程安全的意思。下面我們要講到的Queue模塊就是一種線(xiàn)程安全的隊(duì)列數(shù)據(jù)結(jié)構(gòu),所以我們可以放心的在多線(xiàn)程編程中使用它。

***我們就要來(lái)講講至關(guān)重要的線(xiàn)程阻塞這個(gè)概念了。當(dāng)我們?cè)敿?xì)學(xué)習(xí)完threading模塊之后,大概就知道如何創(chuàng)建和啟動(dòng)線(xiàn)程了。但是如果我們把線(xiàn)程創(chuàng)建好了,然后調(diào)用了start方法,那么我們會(huì)發(fā)現(xiàn)好像整個(gè)程序立馬就結(jié)束了,這是怎么回事呢?其實(shí)這是因?yàn)槲覀冊(cè)谥骶€(xiàn)程中只有負(fù)責(zé)啟動(dòng)子線(xiàn)程的代碼,也就意味著主線(xiàn)程只有啟動(dòng)子線(xiàn)程的功能,至于子線(xiàn)程執(zhí)行的那些代碼,他們本質(zhì)上只是寫(xiě)在類(lèi)里面的一個(gè)方法,并沒(méi)在主線(xiàn)程里面真正去執(zhí)行他,所以主線(xiàn)程啟動(dòng)完子線(xiàn)程之后他的本職工作就已經(jīng)全部完成了,已經(jīng)光榮退場(chǎng)了。既然主線(xiàn)程都退場(chǎng)了,那么python進(jìn)程就跟著結(jié)束了,那么其他線(xiàn)程也就沒(méi)有內(nèi)存空間繼續(xù)執(zhí)行了。所以我們應(yīng)該是要讓主線(xiàn)程大哥等到所有的子線(xiàn)程小弟全部執(zhí)行完畢再光榮退場(chǎng),那么在線(xiàn)程對(duì)象中有什么方法能夠把主線(xiàn)程卡住呢?thread.sleep嘛?這確實(shí)是個(gè)辦法,但是究竟應(yīng)該讓主線(xiàn)程sleep多久呢?我們并不能準(zhǔn)確知道執(zhí)行完一個(gè)任務(wù)要多久時(shí)間,肯定不能用這個(gè)辦法。所以我們這個(gè)時(shí)候應(yīng)該上網(wǎng)查詢(xún)一下有什么辦法能夠讓子線(xiàn)程“卡住”主線(xiàn)程呢?“卡住”這個(gè)詞好像太粗鄙了,其實(shí)說(shuō)專(zhuān)業(yè)一點(diǎn),應(yīng)該叫做“阻塞”,所以我們可以查詢(xún)“python   子線(xiàn)程阻塞主線(xiàn)程”,如果我們會(huì)正確使用搜索引擎的話(huà),應(yīng)該會(huì)查到一個(gè)方法叫做join(),沒(méi)錯(cuò),這個(gè)join()方法就是子線(xiàn)程用于阻塞主線(xiàn)程的方法,當(dāng)子線(xiàn)程還未執(zhí)行完畢的時(shí)候,主線(xiàn)程運(yùn)行到含有join()方法的這一行就會(huì)卡在那里,直到所有線(xiàn)程都執(zhí)行完畢才會(huì)執(zhí)行join()方法后面的代碼。

Queue模塊(隊(duì)列):

假設(shè)有一個(gè)這樣的場(chǎng)景,我們需要抓取一個(gè)人的博客,我們知道這個(gè)人的博客有兩個(gè)頁(yè)面,一個(gè)list.php頁(yè)面顯示的是此博客的所有文章鏈接,還有一個(gè)view.php頁(yè)面顯示的是一篇文章的具體內(nèi)容。

如果我們要把這個(gè)人的博客里面所有文章內(nèi)容抓取下來(lái),編寫(xiě)單線(xiàn)程爬蟲(chóng)的思路是:先用正則表達(dá)式把這個(gè)list.php頁(yè)面的所有鏈接a標(biāo)簽的href屬性抓取下來(lái),存入一個(gè)名字叫做article_list的數(shù)組(在python中不叫數(shù)組,叫做list,中文名列表),然后再用一個(gè)for循環(huán)遍歷這個(gè)article_list數(shù)組,用各種抓取網(wǎng)頁(yè)內(nèi)容的函數(shù)把內(nèi)容抓取下來(lái)然后存入數(shù)據(jù)庫(kù)。

如果我們要編寫(xiě)一個(gè)多線(xiàn)程爬蟲(chóng)來(lái)完成這個(gè)任務(wù)的話(huà),就假設(shè)我們的程序用10個(gè)線(xiàn)程把,那么我們就要想辦法把之前抓取的article_list平均分成10份,分別把每一份分配給其中一個(gè)子線(xiàn)程。

但是問(wèn)題來(lái)了,如果我們的article_list數(shù)組長(zhǎng)度不是10的倍數(shù),也就是文章數(shù)量并不是10的整數(shù)倍,那么***一個(gè)線(xiàn)程就會(huì)比別的線(xiàn)程少分配到一些任務(wù),那么它將會(huì)更快的結(jié)束。

如果僅僅是抓取這種只有幾千字的博客文章這看似沒(méi)什么問(wèn)題,但是如果我們一個(gè)任務(wù)(不一定是抓取網(wǎng)頁(yè)的任務(wù),有可能是數(shù)學(xué)計(jì)算,或者圖形渲染等等耗時(shí)任務(wù))的運(yùn)行時(shí)間很長(zhǎng),那么這將造成極大地資源和時(shí)間浪費(fèi)。我們多線(xiàn)程的目的就是盡可能的利用一切計(jì)算資源并且計(jì)算時(shí)間,所以我們要想辦法讓任務(wù)能夠更加科學(xué)合理的分配。

并且我還要考慮一種情況,就是文章數(shù)量很大的情況下,我們要既能快速抓取到文章內(nèi)容,又能盡快的看到我們已經(jīng)抓取到的內(nèi)容,這種需求在很多CMS采集站上經(jīng)常會(huì)體現(xiàn)出來(lái)。

比如說(shuō)我們現(xiàn)在要抓取的目標(biāo)博客,有幾千萬(wàn)篇文章,通常這種情況下博客都會(huì)做分頁(yè)處理,那么我們?nèi)绻凑丈厦娴膫鹘y(tǒng)思路先抓取完list.php的所有頁(yè)面起碼就要幾個(gè)小時(shí)甚至幾天,老板如果希望你能夠盡快顯示出抓取內(nèi)容,并且盡快將已經(jīng)抓取到的內(nèi)容展現(xiàn)到我們的CMS采集站上,那么我們就要實(shí)現(xiàn)一邊抓取list.php并且把已經(jīng)抓取到的數(shù)據(jù)丟入一個(gè)article_list數(shù)組,一邊用另一個(gè)線(xiàn)程從article_list數(shù)組中提取已經(jīng)抓取到的文章URL地址,然后這個(gè)線(xiàn)程再去對(duì)應(yīng)的URL地址中用正則表達(dá)式取到博客文章內(nèi)容。如何實(shí)現(xiàn)這個(gè)功能呢?

我們就需要同時(shí)開(kāi)啟兩類(lèi)線(xiàn)程,一類(lèi)線(xiàn)程專(zhuān)門(mén)負(fù)責(zé)抓取list.php中的url然后丟入article_list數(shù)組,另外一類(lèi)線(xiàn)程專(zhuān)門(mén)負(fù)責(zé)從article_list中提取出url然后從對(duì)應(yīng)的view.php頁(yè)面中抓取出對(duì)應(yīng)的博客內(nèi)容。

但是我們是否還記得前面提到過(guò)線(xiàn)程安全這個(gè)概念?前一類(lèi)線(xiàn)程一邊往article_list數(shù)組中寫(xiě)入數(shù)據(jù),另外那一類(lèi)的線(xiàn)程從article_list中讀取數(shù)據(jù)并且刪除已經(jīng)讀取完畢的數(shù)據(jù)。但是python中l(wèi)ist并不是線(xiàn)程安全版本的數(shù)據(jù)結(jié)構(gòu),因此這樣操作會(huì)導(dǎo)致不可預(yù)料的錯(cuò)誤。所以我們可以嘗試使用一個(gè)更加方便且線(xiàn)程安全的數(shù)據(jù)結(jié)構(gòu),這就是我們的子標(biāo)題中所提到的Queue隊(duì)列數(shù)據(jù)結(jié)構(gòu)。

同樣Queue也有一個(gè)join()方法,這個(gè)join()方法其實(shí)和上一個(gè)小節(jié)所講到的threading中join()方法差不多,只不過(guò)在Queue中,join()的阻塞條件是當(dāng)隊(duì)列不為空空的時(shí)候才阻塞,否則繼續(xù)執(zhí)行join()后面的代碼。在這個(gè)爬蟲(chóng)中我便使用了這種方法來(lái)阻塞主線(xiàn)程而不是直接通過(guò)線(xiàn)程的join方式來(lái)阻塞主線(xiàn)程,這樣的好處是可以不用寫(xiě)一個(gè)死循環(huán)來(lái)判斷當(dāng)前任務(wù)隊(duì)列中是否還有未執(zhí)行完的任務(wù),讓程序運(yùn)行更加高效,也讓代碼更加優(yōu)雅。

還有一個(gè)細(xì)節(jié)就是在python2.7中隊(duì)列模塊的名字是Queue,而在python3.x中已經(jīng)改名為queue,就是首字母大小寫(xiě)的區(qū)別,大家如果是復(fù)制網(wǎng)上的代碼,要記得這個(gè)小區(qū)別。

getopt模塊:

如果大家學(xué)過(guò)c語(yǔ)言的話(huà),對(duì)這個(gè)模塊應(yīng)該會(huì)很熟悉,他就是一個(gè)負(fù)責(zé)從命令行中的命令里面提取出附帶參數(shù)的模塊。比如說(shuō)我們通常在命令行中操作mysql數(shù)據(jù)庫(kù),就是輸入mysql  -h227.0.0.1 -uroot -p,其中mysql后面的“-h227.0.0.1 -uroot -p”就是可以獲取的參數(shù)部分。

我們平時(shí)在編寫(xiě)爬蟲(chóng)的時(shí)候,有一些參數(shù)是需要用戶(hù)自己手動(dòng)輸入的,比如說(shuō)mysql的主機(jī)IP,用戶(hù)名密碼等等。為了讓我們的程序更加友好通用,有一些配置項(xiàng)是不需要硬編碼在代碼里面,而是在執(zhí)行他的時(shí)候我們動(dòng)態(tài)傳入,結(jié)合getopt模塊我們就可以實(shí)現(xiàn)這個(gè)功能。

hashlib(哈希):

哈希本質(zhì)上就是一類(lèi)數(shù)學(xué)算法的集合,這種數(shù)學(xué)算法有個(gè)特性就是你給定一個(gè)參數(shù),他能夠輸出另外一個(gè)結(jié)果,雖然這個(gè)結(jié)果很短,但是他可以近似認(rèn)為是***的。比如說(shuō)我們平時(shí)聽(tīng)過(guò)的md5,sha-1等等,他們都屬于哈希算法。他們可以把一些文件,文字經(jīng)過(guò)一系列的數(shù)學(xué)運(yùn)算之后變成短短不到一百位的一段數(shù)字英文混合的字符串。

python中的hashlib模塊就為我們封裝好了這些數(shù)學(xué)運(yùn)算函數(shù),我們只需要簡(jiǎn)單的調(diào)用它就可以完成哈希運(yùn)算。

為什么在我這個(gè)爬蟲(chóng)中用到了這個(gè)包呢?因?yàn)樵谝恍┙涌谡?qǐng)求中,服務(wù)器需要帶上一些校驗(yàn)碼,保證接口請(qǐng)求的數(shù)據(jù)沒(méi)有被篡改或者丟失,這些校驗(yàn)碼一般都是hash算法,所以我們需要用到這個(gè)模塊來(lái)完成這種運(yùn)算。

json:

很多時(shí)候我們抓取到的數(shù)據(jù)不是html,而是一些json數(shù)據(jù),json本質(zhì)上只是一段含有鍵值對(duì)的字符串,如果我們需要提取出其中特定的字符串,那么我們需要json這個(gè)模塊來(lái)將這個(gè)json字符串轉(zhuǎn)換為dict類(lèi)型方便我們操作。

re(正則表達(dá)式):

有的時(shí)候我們抓取到了一些網(wǎng)頁(yè)內(nèi)容,但是我們需要將網(wǎng)頁(yè)中的一些特定格式的內(nèi)容提取出來(lái),比如說(shuō)電子郵箱的格式一般都是前面幾位英文數(shù)字字母加一個(gè)@符號(hào)加http://xxx.xxx的域名,而要像計(jì)算機(jī)語(yǔ)言描述這種格式,我們可以使用一種叫做正則表達(dá)式的表達(dá)式來(lái)表達(dá)出這種格式,并且讓計(jì)算機(jī)自動(dòng)從一大段字符串中將符合這種特定格式的文字匹配出來(lái)。

sys:

這個(gè)模塊主要用于處理一些系統(tǒng)方面的事情,在這個(gè)爬蟲(chóng)中我用他來(lái)解決輸出編碼問(wèn)題。

time:

稍微學(xué)過(guò)一點(diǎn)英語(yǔ)的人都能夠猜出來(lái)這個(gè)模塊用于處理時(shí)間,在這個(gè)爬蟲(chóng)中我用它來(lái)獲取當(dāng)前時(shí)間戳,然后通過(guò)在主線(xiàn)程末尾用當(dāng)前時(shí)間戳減去程序開(kāi)始運(yùn)行時(shí)的時(shí)間戳,得到程序的運(yùn)行時(shí)間。

如何使用Python編寫(xiě)多線(xiàn)程爬蟲(chóng)抓取百度貼吧郵箱與手機(jī)號(hào)

如圖所示,開(kāi)50個(gè)線(xiàn)程抓取100頁(yè)(每頁(yè)30個(gè)帖子,相當(dāng)于抓取了3000個(gè)帖子)貼吧帖子內(nèi)容并且從中提取出手機(jī)郵箱這個(gè)步驟共耗時(shí)330秒。

urllib和urllib2:

這兩個(gè)模塊都是用于處理一些http請(qǐng)求,以及url格式化方面的事情。我的爬蟲(chóng)http請(qǐng)求部分的核心代碼就是使用這個(gè)模塊完成的。

MySQLdb:

這是一個(gè)第三方模塊,用于在python中操作mysql數(shù)據(jù)庫(kù)。

這里我們要注意一個(gè)細(xì)節(jié)問(wèn)題:mysqldb模塊并不是線(xiàn)程安全版本,意味著我們不能在多線(xiàn)程中共享同一個(gè)mysql連接句柄。所以大家可以在我的代碼中看到,我在每個(gè)線(xiàn)程的構(gòu)造函數(shù)中都傳入了一個(gè)新的mysql連接句柄。因此每個(gè)子線(xiàn)程只會(huì)用自己獨(dú)立的mysql連接句柄。

cmd_color_printers:

這也是一個(gè)第三方模塊,網(wǎng)上能夠找到相關(guān)代碼,這個(gè)模塊主要用于向命令行中輸出彩色字符串。比如說(shuō)我們通常爬蟲(chóng)出現(xiàn)錯(cuò)誤,要輸出紅色的字體會(huì)比較顯眼,就要使用到這個(gè)模塊。

自動(dòng)化爬蟲(chóng)的錯(cuò)誤處理:

如何使用Python編寫(xiě)多線(xiàn)程爬蟲(chóng)抓取百度貼吧郵箱與手機(jī)號(hào)

如果大家在網(wǎng)絡(luò)質(zhì)量不是很好的環(huán)境下使用該爬蟲(chóng),會(huì)發(fā)現(xiàn)有的時(shí)候會(huì)報(bào)如圖所示的異常,這是我為了偷懶并沒(méi)有寫(xiě)各種異常處理的邏輯。

通常情況下我們?nèi)绻帉?xiě)高度自動(dòng)化的爬蟲(chóng),那么就需要預(yù)料到我們的爬蟲(chóng)可能會(huì)遇到的所有異常情況,針對(duì)這些異常情況做處理。

比如說(shuō)如圖所示的錯(cuò)誤,我們就應(yīng)該把當(dāng)時(shí)正在處理的任務(wù)重新塞入任務(wù)隊(duì)列,否則我們就會(huì)出現(xiàn)遺漏信息的情況。這也是爬蟲(chóng)編寫(xiě)的一個(gè)復(fù)雜點(diǎn)。

以上就是如何使用Python編寫(xiě)多線(xiàn)程爬蟲(chóng)抓取百度貼吧郵箱與手機(jī)號(hào),小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI