Python爬取鬥圖啦,媽媽再也不會擔心我無圖可刷了

〆 小源。發表於2019-03-07

本文同步發表於我的微信公眾號,掃一掃文章底部的二維碼或在微信搜尋 極客導航 即可關注,每個工作日都有文章更新。

一、概況

我們終於把Request網路請求庫和Xpath解析庫的基本用法學的差不多了,終於可以爬一些自己想爬的網站了。那我們拿什麼網站做入門案例呢?好像刷圖表情挺火的,那麼從爬取表情的網站入手,爬取我們自己想要的表情,做一個刷圖達人。我想讓我的硬碟這樣:

Python爬取鬥圖啦,媽媽再也不會擔心我無圖可刷了
因為我太想進步了。
在這裡插入圖片描述

二、分析

我們爬取一個叫鬥圖啦(https://www.doutula.com/photo/list/)的網站,來爬取他們的最新表情。

網站描述

  • URL分析 因為表情有很多,網站都會做分頁處理,首先我們先分析出URL地址的變化,就是下面這個樣子: 第一頁:https://www.doutula.com/photo/list/?page=1 第二頁:https://www.doutula.com/photo/list/?page=2 第三頁:https://www.doutula.com/photo/list/?page=3

  • 表情圖片地址提取分析

    通過檢視瀏覽器原始碼,我們大概發現了圖片所在的標籤以及圖片的地址。 注意:有的圖片是GIF型別,而有的圖片是JPG型別。

    在這裡插入圖片描述
    通過在瀏覽器Xpath外掛分析,提取了下面圖片地址:
    在這裡插入圖片描述
    但是我們發現裡面有些是靜態圖片資源,我們在上面也看到圖片地址有三個,那麼我們在來看看其他屬性是否能提取出網路圖片地址。
    在這裡插入圖片描述
    通過用data-original屬性提取,這次我們發現裡面沒了靜態資源,都是網路圖片地址,這個好像可以用。

三、實現

下面是大概邏輯實現:

import requests
from lxml import etree


class DouTuLaSpider():

    def __init__(self):
        # 預設第一頁開始
        self.pn = 1
        # 預設URL
        self.url = 'https://www.doutula.com/photo/list/?page='

        # 新增請求頭,模擬瀏覽器
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
        }

    # 發起請求
    def loadpage(self):
        # 拼接請求地址
        req_url = self.url + str(self.pn)  # https://www.doutula.com/photo/list/?page=1

        # 發起請求
        reponse = requests.get(url=req_url, headers=self.headers)

        # 用UTF-8進行編碼
        content = reponse.content.decode('utf-8')

        # 構造xpath解析物件
        html = etree.HTML(content)

        # 先取出這個div下面的所有a標籤
        a_list = html.xpath('//div[@class="page-content text-center"]//a')

        for a in a_list:
            # 在從當前的a標籤取下面的img標籤的data-original屬性,取返回列表的第一個值。注意前面有個.
            img_url = a.xpath('./img/@data-original')[0]

            print(img_url)


if __name__ == "__main__":
    dtls = DouTuLaSpider()
    dtls.loadpage()

#列印
https://ws4.sinaimg.cn/bmiddle/9150e4e5gy1g0sad0axupj204t0410sj.jpg
https://ws4.sinaimg.cn/bmiddle/9150e4e5gy1g0sad1qossg206o06ca9x.gif
https://ws4.sinaimg.cn/bmiddle/9150e4e5gy1g0sacyw5wwj207806mmxc.jpg
https://ws1.sinaimg.cn/bmiddle/9150e4e5gy1g0sacxbehoj205d05dq2w.jpg
https://ws4.sinaimg.cn/bmiddle/9150e4e5gy1g0sacu8fy7j20b40b40sv.jpg
https://ws1.sinaimg.cn/bmiddle/9150e4e5gy1g0sacqc75fj205i058aaz.jpg
https://ws3.sinaimg.cn/bmiddle/9150e4e5gy1g0sacso1lbj20u00tamyx.jpg
https://ws1.sinaimg.cn/bmiddle/9150e4e5gy1g0sacod9zzg206o06o40v.gif
https://ws4.sinaimg.cn/bmiddle/9150e4e5gy1g0sachx559j20zk0k0wgo.jpg
......
複製程式碼

第一頁所有的表情圖片地址,我們已經全部爬取下來了,接下來就是把爬取圖片地址通過傳送網路請求下載到本地,這個時候我們需要考慮兩個問題:

  • 圖片的名字怎麼命名?
    在這裡插入圖片描述
    我們在去看了一下原始碼,發現alt屬性的值可以當做圖片的名字,所以在爬取圖片地址的時候也需要把alt屬性的值提取出來。
  • 圖片的字尾是什麼? 因為我們有圖片的網路地址,我們可以通過字串擷取,把圖片地址的字尾擷取下來。

兩個問題實現:

import requests
from lxml import etree
import os


class DouTuLaSpider():

    def __init__(self):
        # 預設第一頁開始
        self.pn = 1
        # 預設URL
        self.url = 'https://www.doutula.com/photo/list/?page='

        # 新增請求頭,模擬瀏覽器
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
        }

    # 發起請求
    def loadpage(self):
        # 拼接請求地址
        req_url = self.url + str(self.pn)  # https://www.doutula.com/photo/list/?page=1

        # 發起請求
        reponse = requests.get(url=req_url, headers=self.headers)

        # 用UTF-8進行編碼
        content = reponse.content.decode('utf-8')

        # 構造xpath解析物件
        html = etree.HTML(content)

        # 先取出這個div下面的所有a標籤
        a_list = html.xpath('//div[@class="page-content text-center"]//a')

        for a in a_list:
            # 在從當前的a標籤取下面的img標籤的data-original屬性,取返回列表的第一個值。注意前面有個.
            img_url = a.xpath('./img/@data-original')[0]
            # 圖片名字
            img_name = a.xpath('./img/@alt')[0]

            print(img_url)

            #下載圖片
            self.loadimg(img_url, img_name)

    #發起圖片請求
    def loadimg(self, img_url, img_name):
        folder = 'doutu'#本地資料夾名字
        if not os.path.exists(folder):#如果資料夾不存在
            os.mkdir(folder)#建立資料夾

        # 拼接本地圖片路徑
        path = folder + "/" + img_name + img_url[-4::]

        # 發起圖片請求
        reponse = requests.get(url=img_url, headers=self.headers)

        # 圖片二進位制資料
        content = reponse.content

        #儲存圖片
        self.saveimg(path,content)

    #儲存圖片
    def saveimg(self,path,content):
        with open(path,'wb') as f:
            f.write(content)


if __name__ == "__main__":
    dtls = DouTuLaSpider()
    dtls.loadpage()

複製程式碼

最終的我的本地資料夾,裝了許多我日思夜想的表情。這只是第一頁,我們需要硬碟被裝紅的那種感覺,我們要實現多頁爬取,先用迴圈代替吧~

在這裡插入圖片描述
我們在程式碼最下面加了一個迴圈,把每次的數值賦值給頁碼。這樣就會不停的傳送請求了。

if __name__ == "__main__":
    dtls = DouTuLaSpider()
    for i in range(1,100):#1-100頁
        print('爬取第%d頁'%i)
        dtls.pn = i #把每頁賦值給pn
        dtls.loadpage()

複製程式碼

不爬了,不爬了,圖片太多。我的硬碟好像有點裝不下了,最終我們讓媽媽不用擔心了。

四、總結

我們用一個簡單的例子,入門了爬蟲。爬蟲入門相對比較簡單,但是在爬取的時候也許我們需要考慮的幾個點:

  • URL地址怎麼變化?(動態網站先不考慮)
  • 提取內容在哪裡?(先用xpath大概獲取位置)
  • 請求的網站原始碼跟瀏覽器裡面的原始碼是否有區別(以請求下來的原始碼為準)

歡迎關注我的公眾號,我們一起學習。

在這裡插入圖片描述

相關文章