前言
想必大家都是比較喜歡美女圖片吧!沒事不要隱瞞了,愛美之心人人皆知。小編也是最近也是比較無聊就爬取了一下了壁紙、圖片啥的。于是加上了一些代碼,把整個網(wǎng)頁的壁紙全部都爬取下來了。
目錄一:概覽
在電腦上,創(chuàng)建一個文件夾用來存放爬取彼岸桌面的圖片
此文件夾下有25個文件夾,對應(yīng)分類
每個分類文件夾下有若干個文件夾,對應(yīng)頁碼
頁碼文件夾下,存放圖片文件
目錄二:環(huán)境準備
環(huán)境準備:怎么使用VSCode編寫Python代碼?
requests:通過http請求獲取頁面,官方文檔
lxml:是python的一個解析庫,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高
Beautiful Soup4:可以從HTML或XML文件中提取數(shù)據(jù)
在終端中分別輸入以下pip命令,安裝它們
python -m pip install beautifulsoup4
python -m pip install lxml
python -m pip install requests
注意:光理論是不夠的。這里送大家一套2020最新企業(yè)Pyhon項目實戰(zhàn)視頻教程,點擊此處 進來獲取 跟著練習下,希望大家一起進步哦!
目錄三:分析頁面結(jié)構(gòu)
因為我的電腦的分辨率為1920 × 1080,所以我爬取的圖片的分辨率為此
彼岸桌面壁紙?zhí)峁┝嗽S多分類供我們?yōu)g覽:日歷、動漫、風景、美女、游戲、影視、動態(tài)、唯美、設(shè)計…
4k分類下的壁紙是該網(wǎng)站收益的重要資源,而且我們有4k壁紙的需求,對其不進行爬取
CSS選擇器:#header > div.head > ul > li:nth-child(1) > div > a,定位到包裹分類的a標簽
我以唯美分類下的壁紙,來講解接下來怎么爬取圖片
1.總共有73頁,除了最后一頁,每頁有18張圖片
但是在代碼中我們最好需要自動獲取總頁碼,嗯,彼岸桌面壁紙網(wǎng)站的結(jié)構(gòu)是真的舒服,基本上每個頁碼的HTML結(jié)構(gòu)都是類似的
CSS選擇器:div.page a,定位到包裹頁碼數(shù)的a標簽,只有6個
并且每頁的第三張圖片都是一樣的廣告,需要在代碼中把它過濾掉
每個分頁的超鏈接很清晰:http://www.netbian.com/weimei/index_x.htm
x 恰好為該頁的頁碼
注意:在分類下看到的圖片是略縮圖,分辨率都較低;要得到1920 × 1080分辨率的該圖,需要進行兩次跳轉(zhuǎn)
以下圖為例
在分類頁面中我們可以直接獲取該圖片的url,但很可惜,它的分辨率并不令人滿意;
通過檢查,很明顯的看到,在分類頁中展示的每一個圖片都指向另一個超鏈接
CSS選擇器:div#main div.list ul li a,定位到包裹圖片的a標簽
點擊該圖片,第一次跳轉(zhuǎn),轉(zhuǎn)到新的鏈接,頁面中顯示有下列內(nèi)容:
CSS選擇器:div#main div.endpage div.pic div.pic-down a,定位到包裹圖片的a標簽
點擊下載壁紙(1920 × 1080)的按鈕,第二次跳轉(zhuǎn),轉(zhuǎn)向一個新的鏈接,終于達成目的,該鏈接中顯示的圖片的分辨率為 1920 × 1080
一波三折,終于給我找到了該圖片的1920 × 1080高清圖
CSS選擇器:div#main table a img,定位到該圖片的img標簽
經(jīng)過本人爬取檢驗,其中有極個別圖片由于很多零碎的問題而下載失敗,還有少部分圖片因為網(wǎng)站雖然提供1920 × 1080分辨率的下載按鈕卻給了其它分辨率
目錄四:代碼分析
下文中凡是?加粗內(nèi)容,請按照我的解釋,根據(jù)自身情況進行修改
第一步:設(shè)置全局變量
index = 'http://www.netbian.com' # 網(wǎng)站根地址
interval = 10 # 爬取圖片的間隔時間
firstDir = 'D:/zgh/Pictures/netbian' # 總路徑
classificationDict = {} # 存放網(wǎng)站分類子頁面的信息
index ,要爬取網(wǎng)頁的網(wǎng)站根地址,代碼中爬取圖片需要使用其拼接完整url
interval,我們?nèi)ヅ廊∫粋€網(wǎng)站的內(nèi)容時要考慮到該網(wǎng)站服務(wù)器的承受能力,短時間內(nèi)爬取該網(wǎng)站大量內(nèi)容會給該網(wǎng)站服務(wù)器造成巨大壓力,我們需要在爬取時設(shè)置間隔時間
單位:秒
由于我要爬取彼岸桌面網(wǎng)站的全部高清圖片,若集中在短時間內(nèi)爬取,一方面會給網(wǎng)站服務(wù)器巨大的壓力,一方面網(wǎng)站服務(wù)器會將我們的鏈接強制斷掉,所以我設(shè)置的每張圖片爬取時間間隔為10秒;如果你只是爬取少量圖片,可以將間隔時間設(shè)置的短點
firstDir,爬取圖片存放在你電腦上的根路徑;代碼中爬取圖片時,在一級目錄下會按照彼岸桌面唯美分類下的分頁頁碼生成文件夾并存放圖片
classificationDict,存放網(wǎng)站下分類指向的url、對應(yīng)的分類文件夾路徑
第二步:獲取頁面篩選后的內(nèi)容列表
寫一個函數(shù),獲取頁面篩選后的內(nèi)容數(shù)組傳進來兩個參數(shù)
url:該網(wǎng)頁的url
select:選擇器(與CSS中的選擇器無縫對接,我很喜歡,定位到HTML中相應(yīng)的元素)
返回一個列表
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,作用是假裝是個用戶訪問該網(wǎng)站,為了保證爬蟲的成功率,每一次爬取頁面隨機抽取一個headers
encoding ,該網(wǎng)站的編碼
第三步:獲取全部分類的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壁紙,因權(quán)限問題無法爬取,直接跳過
continue
secondDir = firstDir + '/' + text # 分類目錄
url = index + href # 分類子頁面url
global classificationDict
classificationDict[text] = {
'path': secondDir,
'url': url
}
接下來的代碼,我以唯美分類下的壁紙,來講解怎么通過跳轉(zhuǎn)兩次鏈接爬取高清圖片
第四步:獲取分類頁面下所有分頁的url
大部分分類的分頁大于等于6頁,可以直接使用上面定義的screen函數(shù),select定義為div.page a,然后screen函數(shù)返回的列表中第6個元素可以獲取我們需要的最后一頁頁碼
但是,有的分類的分頁小于6頁,比如:
需要重新寫一個篩選函數(shù),通過兄弟元素來獲取
# 獲取頁碼
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)
由于該網(wǎng)站的HTML結(jié)構(gòu)非常清晰,所以代碼寫起來簡單明了
第五步:獲取分頁下圖片所指url
通過檢查,可以看到獲取到的url為相對地址,需要將其轉(zhuǎn)化為絕對地址
select = 'div#main div.list ul li a'
imgUrls = screen(url, select)
通過這兩行代碼獲取的列表中的值,形如此:
<a href="/desk/21237.htm" target="_blank" title="星空 女孩 觀望 唯美夜景壁紙 更新時間:2019-12-06"><img alt="星空 女孩 觀望 唯美夜景壁紙" src="http://img.netbian.com/file/newc/e4f018f89fe9f825753866abafee383f.jpg"/><b>星空 女孩 觀望 唯美夜景壁紙</b></a>
需要對獲取的列表進行處理
獲取a標簽中的href屬性值,并將其轉(zhuǎn)化為絕對地址,這是第一次跳轉(zhuǎn)所需要的url
第六步:定位到 1920 × 1080 分辨率圖片
# 定位到 1920 1080 分辨率圖片
def handleImgs(links, path):
for link in links:
href = link.get('href')
if(href == 'http://pic.netbian.com/'): # 過濾圖片廣告
continue
# 第一次跳轉(zhuǎn)
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')
# 第二次跳轉(zhuǎn)
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)): # 若文件名重復(fù)
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
二:第一次跳轉(zhuǎn)頁面,無我們需要的鏈接
彼岸壁紙網(wǎng)站,對第一次跳轉(zhuǎn)頁面的鏈接,給的都是相對地址
但是極個別圖片直接給的絕對地址,而且給的是該分類網(wǎng)址,所以需要做兩步處理
if('http://' in href):
url = href
else:
url = index + href
...
if(link == []):
print(url + ' 無此圖片,爬取失敗')
continue
下面是第二次跳轉(zhuǎn)頁面所遇問題
三:由于權(quán)限問題無法爬取圖片
if(link == []):
print(url + "該圖片需要登錄才能爬取,爬取失敗")
continue
四:獲取img的alt,作為下載圖片文件的文件名時,名字中攜帶\t 或 文件名不允許的特殊字符:
在Python中,’\t’ 是轉(zhuǎn)義字符:空格
在windows系統(tǒng)當中的文件命名,文件名稱中不能包含?\ / : * ? " < > |?一共9個特殊字符
name = link[0].get('alt').replace('\t', '').replace('|', '').replace(':', '').replace('\\', '').replace('/', '').replace('*', '').replace('?', '').replace('"', '').replace('<', '').replace('>', '')
五:獲取img的alt,作為下載圖片文件的文件名時,名字重復(fù)
path = path + '/' + name + '.jpg'
while(os.path.exists(path)): # 若文件名重復(fù)
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文件
最后
動動你們發(fā)財?shù)男∈?,給小編一個關(guān)注就是小編最大的動力,謝謝!