Python爬蟲簡單實現之Q樂園圖片下載

根據需求寫代碼實現。然而跟我並無什麼關係,我只是打開電腦望着屏幕想着去幹點什麼,因而有了這個所謂的「需求」。html

終於,我發現了Q樂園——究竟是我老了仍是我小了,這是什麼神奇的網站,沒聽過啊,就是下面醬紫兒——正則表達式

(雖然小廣告有點多,一度覺得這並非什麼「正經」的網站...)編程

 

 

我並非二次元,只是以爲動漫圖片還算是「老小皆宜」(「少兒不宜」多尷尬),就決定爬一下動漫圖片好了。就是下面那個樣子:瀏覽器

 

 

鼠標右鍵——查看源代碼,別問我用得什麼瀏覽器。網頁大概就是下面這個樣:框架

我好像看到了圖集名稱,「窗外繁華怒放」(窗內我一口老血),「你已經有別的小朋友了 我本身回家就好啦」(說好的老小皆宜,已經隱隱感覺了到了早*的味道)socket

 

點開一個圖集,看下「窗外繁華怒放」吧,還算美~函數

 

 

而後咱們仍是右鍵查看源代碼(說了不告訴你我用的什麼瀏覽器)——網站

 

裏面的「http://略略略略略略.jpg」就是圖集中圖片對應的地址了,好比http://v1.qzone.cc/pic/201709/27/14/13/59cb41a204354684.jpeg!600x600.jpg,直接複製到瀏覽器中打開就是圖片了——不信試試!url

 

因此,咱們要下載圖片,其實也就是要拿到這些網址。怎麼拿?正則表達式,華麗登場!spa

 

就好比,咱們若是打開了圖集「窗外繁華怒放」,那就能夠直接爬取圖集中圖片的地址了,這一個圖集就搞定了。若是咱們貪得無厭,想要下載更多圖集的圖片怎麼辦?(請依次打開圖集,而後把鼠標放在圖片上,右鍵圖片另存爲——啊,固然是開玩笑的了,畢竟我這麼懶!)

 

因此呢,咱們還要獲取全部圖集的網址。基本思路就是:打開一個圖集網址——獲取圖片連接——圖片下載——打開下一個圖集網址——(這不是廢話嗎?)

 

 

那麼,如何獲取全部圖集網址呢?

其實,咱們第一次查看源代碼的時候提到,好像已經看到了圖集的名稱,是的,圖集的名稱,再回頭去看看,裏面的確已經包含了圖集的網址和名稱了。舉個栗子:

<h5><a href="/haokan/dongman/1349139.html" target="_blank">窗外繁花怒放</a></h5>

這一行裏,/haokan/dongman/1349139.html這部分對應的就是網址,名稱本身看。

 

好了,和獲取圖片網址同樣,爬唄,反正咱們有個不怕累的蟲子(啊?蟲子又是什麼?我是誰?我在哪裏?我在幹什麼?)

 

如今咱們看到的是第一頁,若是咱們還想下載第二頁、第三頁、...全部頁面的圖集怎麼辦?(下載了有啥用?大概有病)

看來咱們只好手動一個一個頁面的打開,而後「放蟲咬圖」!(pi~)

 

好吧,仍是偷懶一下好了。反正咱們就是下載Q樂園(高端大氣上檔次!)中的動漫圖片,咱們發現它的網頁都是有規律的:好比第一頁的網址:http://www.qzone.cc/haokan/dongman/,第二頁的網址:http://www.qzone.cc/haokan/dongman/list_2.html。我猜第三頁的網址是:http://www.qzone.cc/haokan/dongman/list_3.html(麻德,我好聰明怎麼辦?!)

 

因而網址咱們能夠經過列表的方式構造了。(列表!終於聽到了一個正常的詞兒,但其實我,根本沒用到好嗎啊啊啊啊)

 

因此,思路很簡單了,咱們先構造全部頁面的網址集合,對每一個頁面網址爬取該頁面上圖集的網址,而後從圖集的網址上爬取該圖集包含的圖片的網址,而後下載圖片。(感受好輕鬆!其實就是好輕鬆)

 

有幾個小tips:

1.我不想把全部圖片都扔到一個文件夾中,我想按照圖集的名稱分別建立文件夾,而後分別保存。怎麼辦?爬取圖集名稱建立文件夾唄~

2.圖集名稱中包含特殊字符,建立文件夾時極可能會因命名問題出錯,那麼怎麼辦?隨便吧。。。我就隨便一搞,差很少就行。

3.我發現頁面源代碼中沒有包含一共多少頁面,那麼咱們怎麼判斷一共要抓去多少頁面呢?我猜大概不會出現http://www.qzone.cc/haokan/dongman/list_10000.html,一萬頁,這渣網,下到啥時候啊。嗯,仍是隨便吧,我就是隨便一搞,真的差很少就行

4.若是有一張圖片,或者有一個網頁卡了,就是下載不下來或者打不開了怎麼辦?隨便搞搞吧,定個時間,沒反應勞資還不看了,跳過!

5.若是圖集重複了,我想下載到同一個文件夾中,還不想覆蓋原有的圖片怎麼辦?我猜你確定知道隨便搞搞就行,你比我聰明!

6.我忘記了...

 

 

看我「自由派」的代碼吧,大概會編程的人都受不了,框架結構什麼的隨便了,反正我樂意(斜眼)。直接跳過V1.0,V2.0,看V3.0吧!(建議V3.0也不用看,啥用啊)

 

V1.0

#Q樂園圖片下載

#載入模塊:路徑設置、爬蟲、正則表達式
import os
import urllib
import re

#定義函數
#頁面抓取函數
def getHTML(url, dec):
    html = urllib.request.urlopen(url).read()
    html = html.decode(dec)
    return html

#網頁列表獲取
def HtmlToList(html, s):
    pat = re.compile(s)
    ToList = pat.findall(html)
    return ToList
    
#頁面執行函數(圖片下載)
def getIMG(url, path, name):
    imgpath = path+name+'.jpg'
    print('    正在下載第%s張照片...'%name)
    urllib.request.urlretrieve(url, imgpath)



#自定義建立文件夾的函數
def makeDir(path, name):
    topath = path+name
    flag = False
    if not os.path.isdir(topath):
        os.mkdir(topath)
        print('建立文件夾:%s!'%name)
    else:
        flag = True
    topath = topath+'\\'
    return topath,flag

#初始頁面(第一頁)網址
url = r'http://www.qzone.cc/haokan/dongman/'

#正則表達式:匹配每頁上的圖集網址
SetS = r'<h5><a href="/.+?/.+?/(.+?.html)" target="_blank">(.+?)</a></h5>'

#獲取頁面上圖集網址集合
html = getHTML(url, 'UTF-8')
PicSetlist = HtmlToList(html, SetS)

#文件夾準備
path = 'D:\\QLeYuan\\'
name = 'PicSet'

#正則表達式:在圖集網頁中匹配圖片
PicS = r'original="(http://.+?/.+?/.+?/.+?/.+?/.+?/.+?.jpg)" class="lazy"'
#第一頁圖集下載
for bit,dirname in PicSetlist:
    #建立圖集路徑文件夾
    dirname.replace('?','')
    dirpath = path+name+'\\'
    filepath,flag = makeDir(dirpath, dirname)
    #組合圖集url
    seturl = url+bit
    #獲取圖片列表
    html = getHTML(seturl, 'UTF-8')
    PicList = HtmlToList(html, PicS)
    #圖片名稱
    imgname = 0
    for PicUrl in PicList:
        #若是獲取的圖集名稱重複,那麼下載到同一文件夾中並重命名,避免出現同名文件沒法建立的問題
        if flag:
            picname = '1-'+str(imgname)
        else:
            picname = str(imgname)
        #獲取圖片
        getIMG(PicUrl, filepath, picname)
        imgname = imgname+1

 

V2.0

#Q樂園圖片下載

#載入模塊:路徑設置、爬蟲、正則表達式
import os
import urllib
import re

#設置超時處理
import socket

#定義函數
#頁面抓取函數
def getHTML(url, dec):
    html = urllib.request.urlopen(url).read()
    html = html.decode(dec)
    return html

#網頁列表獲取
def HtmlToList(html, s):
    pat = re.compile(s)
    ToList = pat.findall(html)
    return ToList
    
#頁面執行函數(圖片下載)
def getIMG(url, path, name):
    imgpath = path+name+'.jpg'
    urllib.request.urlretrieve(url, imgpath)
    
#自定義建立文件夾的函數
def makeDir(path, name):
    topath = path+name
    flag = False
    if not os.path.isdir(topath):
        print('建立文件夾:%s!'%dirname)
        os.mkdir(topath)
    else:
        flag = True
    topath = topath+'\\'
    return topath,flag

#初始頁面(第一頁)網址
url_1 = r'http://www.qzone.cc/haokan/dongman/'

#文件夾準備
path = 'D:\\QLeYuan\\'
name = 'PicSet'
#正則表達式:匹配每頁上的圖集網址 
SetS = r'<h5><a href="/.+?/.+?/(.+?.html)" target="_blank">(.+?)</a></h5>' 
#正則表達式:匹配全部頁面網址 
UrlS = r'<a href="/.+?/.+?/(.+?.html)">.</a></li>' 
#獲取頁面網址 
html = getHTML(url_1, 'UTF-8') 
UrlList = HtmlToList(html, UrlS) 
#構造第一頁的網址 
UrlList.insert(0,'') 
for root in UrlList: 
    url = url_1+root 
    #獲取頁面上圖集網址集合 
    html = getHTML(url, 'UTF-8') 
    PicSetList = HtmlToList(html, SetS) 
    #正則表達式:在圖集網頁中匹配圖片 
    PicS = r'original="(http://.+?/.+?/.+?/.+?/.+?/.+?/.+?.jpg)" class="lazy"' 
    #第一頁圖集下載 
    for bit,dirname in PicSetList: 
        #建立圖集路徑文件夾 
        dirname = dirname.replace('?','') 
        dirname = dirname.replace('\\','') 
        dirpath = path+name+'\\' 
        filepath,flag = makeDir(dirpath, dirname) 
        #組合圖集url 
        seturl = url_1+bit 
        #獲取圖片列表 
        html = getHTML(seturl, 'UTF-8') 
        PicList = HtmlToList(html, PicS) 
        #圖片名稱 
        imgname = 0 
        for PicUrl in PicList: 
            #若是獲取的圖集名稱重複,那麼下載到同一文件夾中並重命名,避免出現同名文件沒法建立的問題 
            if flag: 
                picname = '1-'+str(imgname) 
            else: 
                picname = str(imgname) 
                #獲取圖片:若是遇到下載異常會提示 
            try: 
                #下載超時會報錯跳過該異常下載其餘 
                socket.setdefaulttimeout(5.0) 
                print(' 正在下載第%s張照片...'%picname) 
                getIMG(PicUrl, filepath, picname) 
            except: 
                print('圖片%d下載異常'%imgname) 
                imgname = imgname+1 
                print('下載完成!')

 

V3.0

#Q樂園圖片下載

#載入模塊:路徑設置、爬蟲、正則表達式
import os
import urllib
import re

#設置超時處理
import socket

#定義函數
#頁面抓取函數
def getHTML(url, dec):
    html = urllib.request.urlopen(url).read()
    html = html.decode(dec)
    return html

#網頁列表獲取
def HtmlToList(html, s):
    pat = re.compile(s)
    ToList = pat.findall(html)
    return ToList
    
#頁面執行函數(圖片下載)
def getIMG(url, path, name):
    imgpath = path+name+'.jpg'
    urllib.request.urlretrieve(url, imgpath)
    
#自定義建立文件夾的函數
def makeDir(path, name):
    topath = path+name
    flag = False
    if not os.path.isdir(topath):
        print('建立文件夾:%s!'%dirname)
        os.mkdir(topath)
    else:
        flag = True
    topath = topath+'\\'
    return topath,flag

#檢查文件夾名是否合法
def checkDirName(name=None):
    if name is None:
        print('name is None.')
    s = r'[;\\/:*?"<>|\r\n]+'
    pat = re.compile(s)
    bug = pat.findall(name)
    if bug:
        for char in bug:
            name = name.replace(char, '_')    
    return name
    
#初始頁面(第一頁)網址
url_1 = r'http://www.qzone.cc/haokan/dongman/'
url = url_1

#文件夾準備
path = 'D:\\QLeYuan\\'
name = 'PicSet'
#正則表達式:匹配每頁上的圖集網址
SetS = r'<h5><a href="/.+?/.+?/(.+?.html)" target="_blank">(.+?)</a></h5>'

#圖集名稱重複下載到同一文件夾
namesame = 1

label = True
root = 2

while label:
    try:
    #獲取頁面上圖集網址集合
        html = getHTML(url, 'UTF-8')
        PicSetList = HtmlToList(html, SetS)
    except:
        print('下載全部頁面已下載完成!或者打開網址出錯!')
        break
    #正則表達式:在圖集網頁中匹配圖片
    PicS = r'original="(http://.+?/.+?/.+?/.+?/.+?/.+?/.+?.jpg)" class="lazy"'
    #第一頁圖集下載
    print('正在下載第%d頁圖集:'%(root-1))
    for bit,dirname in PicSetList:
        #建立圖集路徑文件夾
        dirname = checkDirName(dirname)
        dirpath = path+name+'\\'
        filepath,flag = makeDir(dirpath, dirname)
        #組合圖集url
        seturl = url_1+bit
        #獲取圖片列表
        html = getHTML(seturl, 'UTF-8')
        PicList = HtmlToList(html, PicS)
        #圖片名稱
        imgname = 0
        if flag:
            prename = str(namesame)+'_'
            namesame = namesame+1
        else:
            namesame = 1
            prename = ''
                
        for PicUrl in PicList:
            #若是獲取的圖集名稱重複,那麼下載到同一文件夾中並重命名,避免出現同名文件沒法建立的問題 
            picname = prename+str(imgname)
                #獲取圖片:若是遇到下載異常會提示 
            try:
                #下載超時會報錯跳過該異常下載其餘 
                socket.setdefaulttimeout(5.0)
                print(' 正在下載第%s張照片...'%picname)
                getIMG(PicUrl, filepath, picname)
            except:
                print('圖片%d下載異常'%imgname)
                
            
            imgname = imgname+1
    #更新網址
    url = url_1+'list_'+str(root)+'.html'
    root = root+1 

(能夠搞一搞,不止下載動漫圖片,下載全部的類型的圖片,不難實現。實在沒有什麼意思了...)

 

那麼,下載了圖集長什麼樣子呢?

先看下下載過程大概長什麼樣子(其實根本沒有過程):

 

下載後部分文件夾:

看看「窗外繁華怒放」,圖片是什麼樣子:

我沒有實際運行到最後結束(畢竟渣網速)。我嘗試不實際下載圖片,只看共有多少個圖集,大概有兩三千不是問題,平均一個圖集5張圖片的話,一萬張圖片都是妥妥的。

 

好像壓根沒有說到正則表達式是什麼,爬蟲是什麼,實現技巧是什麼...別問我,反正我也不知道是什麼。還有,別問我是什麼瀏覽器,由於這並不重要,反正什麼瀏覽器都行(白眼)

 

千萬不要把這當作是教程,這大概只是理科生的一篇「隨筆」,吐槽一下近期的部分心情(強調是部分!)。開心就好啊~

 

最後,正經說一句:若有侵權,請聯繫刪除!(麻德,我侵了誰的權,驚恐)

相關文章
相關標籤/搜索