跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

有一個網站,叫做“鬥圖啦”,網址是:https://www.doutula.com/。這裡麵包含了許許多多的有意思的鬥圖圖片,還蠻好玩的。有時候為了鬥圖要跑到這個上面來找表情,實在有點費勁。於是就產生了一個邪惡的想法,可以寫個爬蟲,把所有的表情都給爬下來。這個網站對於爬蟲來講算是比較友好了,他不會限制你的headers,不會限制你的訪問頻率(當然,作為一個有素質的爬蟲工程師,爬完趕緊撤,不要把人家服務器搞垮了),不會限制你的IP地址,因此技術難度不算太高。但是有一個問題,因為這裡要爬的是圖片,而不是文本信息,所以採用傳統的爬蟲是可以完成我們的需求,但是因為是下載圖片所以速度比較慢,可能要爬一兩個小時都說不準。因此這裡我們準備採用多線程爬蟲,一下可以把爬蟲的效率提高好幾倍。

一、分析網站和爬蟲準備工作:

構建所有頁面URL列表:

這裡我們要爬的頁面不是“鬥圖啦”首頁,而是最新表情頁面https://www.doutula.com/photo/list/,這個頁面包含了所有的表情圖片,只是是按照時間來排序的而已。我們把頁面滾動到最下面,可以看到這個最新表情使用的是分頁,當我們點擊第二頁的時候,頁面的URL變成了https://www.doutula.com/photo/list/?page=2,而我們再回到第一頁的時候,page
又變成了1,所以這個翻頁的URL其實很簡單,前面這一串https://www.doutula.com/photo/list/?page=
都是固定的,只是後面跟的數字不一樣而已。並且我們可以看到,這個最新表情總共是有869頁,因此這裡我們可以寫個非常簡單的代碼,來構建一個從1到869的頁面的URL列表:

跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

獲取一個頁面中所有的表情圖片鏈接:

我們已經拿到了所有頁面的鏈接,但是還沒有拿到每個頁面中表情的鏈接。經過分析,我們可以知道,其實每個頁面中表情的HTML元素構成都是一樣的,因此我們只需要針對一個頁面進行分析,其他頁面按照同樣的規則,就可以拿到所有頁面的表情鏈接了。這裡我們以第一頁為例,跟大家講解。首先在頁面中右鍵->檢查->Elements,然後點擊Elements
最左邊的那個小光標,再把鼠標放在隨意一個表情上,這樣下面的代碼就定位到這個表情所在的代碼位置了:

跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

裙更多教程:526929231

可以看到,這個img標籤的class是等於img-responsive lazy image_dtz,然後我們再定位其他表情的img
標籤,發現所有的表情的img標籤,他的class都是img-responsive lazy image_dtz:

跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

因此我們只要把數據從網上拉下來,然後再根據這個規則進行提取就可以了。這裡我們使用了兩個第三方庫,一個是requests,這個庫是專門用來做網絡請求的。第二個庫是bs4,這個庫是專門用來把請求下來的數據進行分析和過濾用的,如果沒有安裝好這兩個庫的,可以使用以下代碼進行安裝(我使用的是python2.7的版本):

跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

然後我們以第一個頁面為例,跟大家講解如何從頁面中獲取所有表情的鏈接:

跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

這樣我們就可以在控制檯看到本頁中所有的表情圖片的鏈接就全部都打印出來了。

下載圖片:

有圖片鏈接後,還要對圖片進行下載處理,這裡我們以一張圖片為例:http://ws2.sinaimg.cn/bmiddle/9150e4e5ly1fhpi3ysfocj205i04aa9z.jpg,來看看Python中如何輕輕鬆鬆下載一張圖片:

跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

這樣就可以下載一張圖片了。

結合以上三部分內容:

以上三部分,分別對,如何構建所有頁面的URL,一個頁面中如何獲取所有表情的鏈接以及下載圖片的方法。接下來把這三部分結合在一起,就可以構建一個完整但效率不高的爬蟲了:

跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

完整代碼

以上這份代碼。可以完整的運行了。但是效率不高,畢竟是在下載圖片,要一個個排隊下載。如果能夠採用多線程,在一張圖片下載的時候,就完全可以去請求其他圖片,而不用繼續等待了。因此效率比較高,以下將該例子改為多線程來實現。

二、多線程下載圖片:

這裡多線程我們使用的是Python自帶的threading模塊。並且我們使用了一種叫做生產者和消費者的模式,生產者專門用來從每個頁面中獲取表情的下載鏈接存儲到一個全局列表中。而消費者專門從這個全局列表中提取表情鏈接進行下載。並且需要注意的是,在多線程中使用全局變量要用鎖來保證數據的一致性。以下是多線程的爬蟲代碼(如果有看不懂的,可以看視頻,講解很仔細):

跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

跟我鬥圖,我用Python爬蟲下載幾個G的表情砸死你

寫在最後:

本教程採用多線程來完成表情的爬取,可以讓爬取效率高出很多倍。Python的多線程雖然有GIL全局解釋器鎖,但在網絡IO處理這一塊表現還是很好的,不用在一個地方一直等待。以上這個例子就很好的說明了多線程的好處。另外,如果你對Python和爬蟲或者框架有相關的興趣,那麼可以群(526929231)一起學習和討論哦(本教程視頻可以入群找我索取)。

相關推薦

推薦中...