Python爬蟲,高清美圖我全都要!爬取你想要的,嘿嘿嘿

想必大家都是比較喜歡美女圖片吧!沒事不要隱瞞了,愛美之心人人皆知。小編也是最近也是比較無聊就爬取了一下了壁紙、圖片啥的。於是加上了一些代碼,把整個網頁的壁紙全部都爬取下來了。

目錄一:概覽

在電腦上,創建一個文件夾用來存放爬取彼岸桌面的圖片

此文件夾下有25個文件夾,對應分類

每個分類文件夾下有若干個文件夾,對應頁碼

頁碼文件夾下,存放圖片文件

目錄二:環境準備

  • 環境準備:怎麼使用VSCode編寫Python代碼?

  • requests:通過http請求獲取頁面,官方文檔

  • lxml:是python的一個解析庫,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高

  • Beautiful Soup4:可以從HTML或XML文件中提取數據

在終端中分別輸入以下pip命令,安裝它們

python -m pip install beautifulsoup4python -m pip install lxmlpython -m pip install requests

  • 注意:光理論是不夠的。這裏送大家一套2020最新企業Pyhon項目實戰視頻教程,點擊此處 進來獲取 跟着練習下,希望大家一起進步哦!

目錄三:分析頁面結構

  • 因爲我的電腦的分辨率爲1920 × 1080,所以我爬取的圖片的分辨率爲此

  • 彼岸桌面壁紙提供了許多分類供我們瀏覽:日曆、動漫、風景、美女、遊戲、影視、動態、唯美、設計…

4k分類下的壁紙是該網站收益的重要資源,而且我們有4k壁紙的需求,對其不進行爬取

  • CSS選擇器:#header > div.head > ul > li:nth-child(1) > div > a,定位到包裹分類的a標籤

我以唯美分類下的壁紙,來講解接下來怎麼爬取圖片

1.總共有73頁,除了最後一頁,每頁有18張圖片

但是在代碼中我們最好需要自動獲取總頁碼,嗯,彼岸桌面壁紙網站的結構是真的舒服,基本上每個頁碼的HTML結構都是類似的

CSS選擇器:div.page a,定位到包裹頁碼數的a標籤,只有6個

並且每頁的第三張圖片都是一樣的廣告,需要在代碼中把它過濾掉

每個分頁的超鏈接很清晰:http://www.netbian.com/weimei/index_x.htm

x 恰好爲該頁的頁碼

注意:在分類下看到的圖片是略縮圖,分辨率都較低;要得到1920 × 1080分辨率的該圖,需要進行兩次跳轉

以下圖爲例

在分類頁面中我們可以直接獲取該圖片的url,但很可惜,它的分辨率並不令人滿意;通過檢查,很明顯的看到,在分類頁中展示的每一個圖片都指向另一個超鏈接

CSS選擇器:div#main div.list ul li a,定位到包裹圖片的a標籤點擊該圖片,第一次跳轉,轉到新的鏈接,頁面中顯示有下列內容:

CSS選擇器:div#main div.endpage div.pic div.pic-down a,定位到包裹圖片的a標籤

點擊下載壁紙(1920 × 1080)的按鈕,第二次跳轉,轉向一個新的鏈接,終於達成目的,該鏈接中顯示的圖片的分辨率爲 1920 × 1080

一波三折,終於給我找到了該圖片的1920 × 1080高清圖

CSS選擇器:div#main table a img,定位到該圖片的img標籤

經過本人爬取檢驗,其中有極個別圖片由於很多零碎的問題而下載失敗,還有少部分圖片因爲網站雖然提供1920 × 1080分辨率的下載按鈕卻給了其它分辨率

目錄四:代碼分析

  • 下文中凡是 加粗內容,請按照我的解釋,根據自身情況進行修改

第一步:設置全局變量

index = 'http://www.netbian.com' # 網站根地址interval = 10 # 爬取圖片的間隔時間firstDir = 'D:/zgh/Pictures/netbian' # 總路徑classificationDict = {} # 存放網站分類子頁面的信息

  • index ,要爬取網頁的網站根地址,代碼中爬取圖片需要使用其拼接完整url

  • interval,我們去爬取一個網站的內容時要考慮到該網站服務器的承受能力,短時間內爬取該網站大量內容會給該網站服務器造成巨大壓力,我們需要在爬取時設置間隔時間

  • 單位:秒

  • 由於我要爬取彼岸桌面網站的全部高清圖片,若集中在短時間內爬取,一方面會給網站服務器巨大的壓力,一方面網站服務器會將我們的鏈接強制斷掉,所以我設置的每張圖片爬取時間間隔爲10秒;如果你只是爬取少量圖片,可以將間隔時間設置的短點

  • firstDir,爬取圖片存放在你電腦上的根路徑;代碼中爬取圖片時,在一級目錄下會按照彼岸桌面唯美分類下的分頁頁碼生成文件夾並存放圖片

  • classificationDict,存放網站下分類指向的url、對應的分類文件夾路徑

第二步:獲取頁面篩選後的內容列表

  • 寫一個函數,獲取頁面篩選後的內容數組傳進來兩個參數url:該網頁的urlselect:選擇器(與CSS中的選擇器無縫對接,我很喜歡,定位到HTML中相應的元素)

  • 返回一個列表

def screen(url, select): html = requests.get(url = url, headers = UserAgent.get_headers()) # 隨機獲取一個headers html.encoding = 'gbk' html = html.text soup = BeautifulSoup(html, 'lxml') return soup.select(select)

  • headers,作用是假裝是個用戶訪問該網站,爲了保證爬蟲的成功率,每一次爬取頁面隨機抽取一個headers

  • encoding ,該網站的編碼

第三步:獲取全部分類的url

# 將分類子頁面信息存放在字典中def init_classification(): url = index select = '#header > div.head > ul > li:nth-child(1) > div > a' classifications = screen(url, select) for c in classifications: href = c.get('href') # 獲取的是相對地址 text = c.string # 獲取分類名 if(text == '4k壁紙'): # 4k壁紙,因權限問題無法爬取,直接跳過 continue secondDir = firstDir + '/' + text # 分類目錄 url = index + href # 分類子頁面url global classificationDict classificationDict[text] = { 'path': secondDir, 'url': url }

接下來的代碼,我以唯美分類下的壁紙,來講解怎麼通過跳轉兩次鏈接爬取高清圖片

第四步:獲取分類頁面下所有分頁的url

大部分分類的分頁大於等於6頁,可以直接使用上面定義的screen函數,select定義爲div.page a,然後screen函數返回的列表中第6個元素可以獲取我們需要的最後一頁頁碼

但是,有的分類的分頁小於6頁,比如:

需要重新寫一個篩選函數,通過兄弟元素來獲取

# 獲取頁碼def screenPage(url, select): html = requests.get(url = url, headers = UserAgent.get_headers()) html.encoding = 'gbk' html = html.text soup = BeautifulSoup(html, 'lxml') return soup.select(select)[0].next_sibling.text

獲取分類頁面下所有分頁的url

url = 'http://www.netbian.com/weimei/'select = '#main > div.page > span.slh'pageIndex = screenPage(secondUrl, select)lastPagenum = int(pageIndex) # 獲取最後一頁的頁碼for i in range(lastPagenum): if i == 0: url = 'http://www.netbian.com/weimei/index.htm' else: url = 'http://www.netbian.com/weimei/index_%d.htm' %(i+1)

由於該網站的HTML結構非常清晰,所以代碼寫起來簡單明瞭

第五步:獲取分頁下圖片所指url

通過檢查,可以看到獲取到的url爲相對地址,需要將其轉化爲絕對地址

select = 'div#main div.list ul li a'imgUrls = screen(url, select)

通過這兩行代碼獲取的列表中的值,形如此:

星空 女孩 觀望 唯美夜景壁紙星空 女孩 觀望 唯美夜景壁紙

  • 需要對獲取的列表進行處理

  • 獲取a標籤中的href屬性值,並將其轉化爲絕對地址,這是第一次跳轉所需要的url

第六步:定位到 1920 × 1080 分辨率圖片

# 定位到 1920 1080 分辨率圖片 def handleImgs(links, path): for link in links: href = link.get('href') if(href == 'http://pic.netbian.com/'): # 過濾圖片廣告 continue # 第一次跳轉 if('http://' in href): # 有極個別圖片不提供正確的相對地址 url = href else: url = index + href select = 'div#main div.endpage div.pic div.pic-down a' link = screen(url, select) if(link == []): print(url + ' 無此圖片,爬取失敗') continue href = link[0].get('href') # 第二次跳轉 url = index + href # 獲取到圖片了 select = 'div#main table a img' link = screen(url, select) if(link == []): print(url + " 該圖片需要登錄才能爬取,爬取失敗") continue name = link[0].get('alt').replace('\t', '').replace('|', '').replace(':', '').replace('\\', '').replace('/', '').replace('*', '').replace('?', '').replace('"', '').replace('<', '').replace('>', '') print(name) # 輸出下載圖片的文件名 src = link[0].get('src') if(requests.get(src).status_code == 404): print(url + ' 該圖片下載鏈接404,爬取失敗') print() continue print() download(src, name, path) time.sleep(interval)

第七步:下載圖片

# 下載操作def download(src, name, path): if(isinstance(src, str)): response = requests.get(src) path = path + '/' + name + '.jpg' while(os.path.exists(path)): # 若文件名重複 path = path.split(".")[0] + str(random.randint(2, 17)) + '.' + path.split(".")[1] with open(path,'wb') as pic: for chunk in response.iter_content(128): pic.write(chunk)

目錄五:代碼的容錯能力

一:過濾圖片廣告

if(href == 'http://pic.netbian.com/'): # 過濾圖片廣告 continue

二:第一次跳轉頁面,無我們需要的鏈接

彼岸壁紙網站,對第一次跳轉頁面的鏈接,給的都是相對地址

但是極個別圖片直接給的絕對地址,而且給的是該分類網址,所以需要做兩步處理

if('http://' in href): url = hrefelse: url = index + href...if(link == []): print(url + ' 無此圖片,爬取失敗') continue

下面是第二次跳轉頁面所遇問題

三:由於權限問題無法爬取圖片

if(link == []): print(url + "該圖片需要登錄才能爬取,爬取失敗") continue

四:獲取img的alt,作爲下載圖片文件的文件名時,名字中攜帶\t 或 文件名不允許的特殊字符:

  • 在Python中,’\t’ 是轉義字符:空格

  • 在windows系統當中的文件命名,文件名稱中不能包含 \ / : * ? " < > | 一共9個特殊字符

name = link[0].get(‘alt’).replace(’\t’, ‘’).replace(’|’, ‘’).replace(’:’, ‘’).replace(’\’, ‘’).replace(’/’, ‘’).replace(’*’, ‘’).replace(’?’, ‘’).replace(’"’, ‘’).replace(’<’, ‘’).replace(’>’, ‘’)

五:獲取img的alt,作爲下載圖片文件的文件名時,名字重複

path = path + '/' + name + '.jpg'while(os.path.exists(path)): # 若文件名重複 path = path.split(".")[0] + str(random.randint(2, 17)) + '.' + path.split(".")[1]

六:圖片鏈接404

比如

if(requests.get(src).status_code == 404): print(url + ' 該圖片下載鏈接404,爬取失敗') print() continue

目錄六:完整代碼

  • 藍奏雲鏈接:Python爬蟲,高清美圖我全都要(彼岸桌面壁紙).zip下載下來解壓後,有兩個python文件

最後

動動你們發財的小手,給小編一個關注就是給我最大的動力,謝謝!

推薦我們的Python學習扣qun:784758214 ,看看前輩們是如何學習的!從基礎的python腳本到web開發、爬蟲、django、數據挖掘等【PDF,實戰源碼】,零基礎到項目實戰的資料都有整理。送給每一位python的小夥伴!每天都有大牛定時講解Python技術,分享一些學習的方法和需要注意的小細節,點擊加入我們的 python學習者聚集地

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章