前言
想必大家都是比較喜歡美女圖片吧!沒(méi)事不要隱瞞了辱魁,愛(ài)美之心人人皆知烟瞧。小編也是最近也是比較無(wú)聊就爬取了一下了壁紙诗鸭、圖片啥的。于是加上了一些代碼参滴,把整個(gè)網(wǎng)頁(yè)的壁紙全部都爬取下來(lái)了强岸。
目錄一:概覽
在電腦上,創(chuàng)建一個(gè)文件夾用來(lái)存放爬取彼岸桌面的圖片
此文件夾下有25個(gè)文件夾砾赔,對(duì)應(yīng)分類
每個(gè)分類文件夾下有若干個(gè)文件夾蝌箍,對(duì)應(yīng)頁(yè)碼
頁(yè)碼文件夾下,存放圖片文件
目錄二:環(huán)境準(zhǔn)備
環(huán)境準(zhǔn)備:怎么使用VSCode編寫Python代碼暴心?
requests:通過(guò)http請(qǐng)求獲取頁(yè)面妓盲,官方文檔
lxml:是python的一個(gè)解析庫(kù),支持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項(xiàng)目實(shí)戰(zhàn)視頻教程筋粗,點(diǎn)擊此處 進(jìn)來(lái)獲取 跟著練習(xí)下,希望大家一起進(jìn)步哦炸渡!
目錄三:分析頁(yè)面結(jié)構(gòu)
因?yàn)槲业碾娔X的分辨率為1920 × 1080娜亿,所以我爬取的圖片的分辨率為此
彼岸桌面壁紙?zhí)峁┝嗽S多分類供我們?yōu)g覽:日歷、動(dòng)漫偶摔、風(fēng)景暇唾、美女、游戲辰斋、影視策州、動(dòng)態(tài)、唯美宫仗、設(shè)計(jì)…
4k分類下的壁紙是該網(wǎng)站收益的重要資源够挂,而且我們有4k壁紙的需求,對(duì)其不進(jìn)行爬取
CSS選擇器:#header > div.head > ul > li:nth-child(1) > div > a藕夫,定位到包裹分類的a標(biāo)簽
我以唯美分類下的壁紙孽糖,來(lái)講解接下來(lái)怎么爬取圖片
1.總共有73頁(yè),除了最后一頁(yè)毅贮,每頁(yè)有18張圖片
但是在代碼中我們最好需要自動(dòng)獲取總頁(yè)碼办悟,嗯,彼岸桌面壁紙網(wǎng)站的結(jié)構(gòu)是真的舒服滩褥,基本上每個(gè)頁(yè)碼的HTML結(jié)構(gòu)都是類似的
CSS選擇器:div.page a病蛉,定位到包裹頁(yè)碼數(shù)的a標(biāo)簽,只有6個(gè)
并且每頁(yè)的第三張圖片都是一樣的廣告,需要在代碼中把它過(guò)濾掉
每個(gè)分頁(yè)的超鏈接很清晰:http://www.netbian.com/weimei/index_x.htm
x 恰好為該頁(yè)的頁(yè)碼
注意:在分類下看到的圖片是略縮圖铺然,分辨率都較低俗孝;要得到1920 × 1080分辨率的該圖,需要進(jìn)行兩次跳轉(zhuǎn)
以下圖為例
在分類頁(yè)面中我們可以直接獲取該圖片的url魄健,但很可惜赋铝,它的分辨率并不令人滿意;
通過(guò)檢查沽瘦,很明顯的看到革骨,在分類頁(yè)中展示的每一個(gè)圖片都指向另一個(gè)超鏈接
CSS選擇器:div#main div.list ul li a,定位到包裹圖片的a標(biāo)簽
點(diǎn)擊該圖片其垄,第一次跳轉(zhuǎn)苛蒲,轉(zhuǎn)到新的鏈接,頁(yè)面中顯示有下列內(nèi)容:
CSS選擇器:div#main div.endpage div.pic div.pic-down a绿满,定位到包裹圖片的a標(biāo)簽
點(diǎn)擊下載壁紙(1920 × 1080)的按鈕臂外,第二次跳轉(zhuǎn),轉(zhuǎn)向一個(gè)新的鏈接喇颁,終于達(dá)成目的漏健,該鏈接中顯示的圖片的分辨率為 1920 × 1080
一波三折,終于給我找到了該圖片的1920 × 1080高清圖
CSS選擇器:div#main table a img橘霎,定位到該圖片的img標(biāo)簽
經(jīng)過(guò)本人爬取檢驗(yàn)蔫浆,其中有極個(gè)別圖片由于很多零碎的問(wèn)題而下載失敗,還有少部分圖片因?yàn)榫W(wǎng)站雖然提供1920 × 1080分辨率的下載按鈕卻給了其它分辨率
目錄四:代碼分析
下文中凡是?加粗內(nèi)容姐叁,請(qǐng)按照我的解釋瓦盛,根據(jù)自身情況進(jìn)行修改
第一步:設(shè)置全局變量
index = 'http://www.netbian.com' # 網(wǎng)站根地址
interval = 10 # 爬取圖片的間隔時(shí)間
firstDir = 'D:/zgh/Pictures/netbian' # 總路徑
classificationDict = {} # 存放網(wǎng)站分類子頁(yè)面的信息
index ,要爬取網(wǎng)頁(yè)的網(wǎng)站根地址外潜,代碼中爬取圖片需要使用其拼接完整url
interval原环,我們?nèi)ヅ廊∫粋€(gè)網(wǎng)站的內(nèi)容時(shí)要考慮到該網(wǎng)站服務(wù)器的承受能力,短時(shí)間內(nèi)爬取該網(wǎng)站大量?jī)?nèi)容會(huì)給該網(wǎng)站服務(wù)器造成巨大壓力处窥,我們需要在爬取時(shí)設(shè)置間隔時(shí)間
單位:秒
由于我要爬取彼岸桌面網(wǎng)站的全部高清圖片嘱吗,若集中在短時(shí)間內(nèi)爬取,一方面會(huì)給網(wǎng)站服務(wù)器巨大的壓力滔驾,一方面網(wǎng)站服務(wù)器會(huì)將我們的鏈接強(qiáng)制斷掉谒麦,所以我設(shè)置的每張圖片爬取時(shí)間間隔為10秒;如果你只是爬取少量圖片哆致,可以將間隔時(shí)間設(shè)置的短點(diǎn)
firstDir绕德,爬取圖片存放在你電腦上的根路徑;代碼中爬取圖片時(shí)摊阀,在一級(jí)目錄下會(huì)按照彼岸桌面唯美分類下的分頁(yè)頁(yè)碼生成文件夾并存放圖片
classificationDict耻蛇,存放網(wǎng)站下分類指向的url剩瓶、對(duì)應(yīng)的分類文件夾路徑
第二步:獲取頁(yè)面篩選后的內(nèi)容列表
寫一個(gè)函數(shù),獲取頁(yè)面篩選后的內(nèi)容數(shù)組傳進(jìn)來(lái)兩個(gè)參數(shù)
url:該網(wǎng)頁(yè)的url
select:選擇器(與CSS中的選擇器無(wú)縫對(duì)接城丧,我很喜歡,定位到HTML中相應(yīng)的元素)
返回一個(gè)列表
def screen(url, select):
html = requests.get(url = url, headers = UserAgent.get_headers()) # 隨機(jī)獲取一個(gè)headers
html.encoding = 'gbk'
html = html.text
soup = BeautifulSoup(html, 'lxml')
return soup.select(select)
headers豌鹤,作用是假裝是個(gè)用戶訪問(wèn)該網(wǎng)站亡哄,為了保證爬蟲(chóng)的成功率,每一次爬取頁(yè)面隨機(jī)抽取一個(gè)headers
encoding 布疙,該網(wǎng)站的編碼
第三步:獲取全部分類的url
# 將分類子頁(yè)面信息存放在字典中
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') # 獲取的是相對(duì)地址
text = c.string # 獲取分類名
if(text == '4k壁紙'): # 4k壁紙蚊惯,因權(quán)限問(wèn)題無(wú)法爬取,直接跳過(guò)
continue
secondDir = firstDir + '/' + text # 分類目錄
url = index + href # 分類子頁(yè)面url
global classificationDict
classificationDict[text] = {
'path': secondDir,
'url': url
}
接下來(lái)的代碼灵临,我以唯美分類下的壁紙截型,來(lái)講解怎么通過(guò)跳轉(zhuǎn)兩次鏈接爬取高清圖片
第四步:獲取分類頁(yè)面下所有分頁(yè)的url
大部分分類的分頁(yè)大于等于6頁(yè),可以直接使用上面定義的screen函數(shù)儒溉,select定義為div.page a宦焦,然后screen函數(shù)返回的列表中第6個(gè)元素可以獲取我們需要的最后一頁(yè)頁(yè)碼
但是,有的分類的分頁(yè)小于6頁(yè)顿涣,比如:
需要重新寫一個(gè)篩選函數(shù)波闹,通過(guò)兄弟元素來(lái)獲取
# 獲取頁(yè)碼
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
獲取分類頁(yè)面下所有分頁(yè)的url
url = 'http://www.netbian.com/weimei/'
select = '#main > div.page > span.slh'
pageIndex = screenPage(secondUrl, select)
lastPagenum = int(pageIndex) # 獲取最后一頁(yè)的頁(yè)碼
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)非常清晰,所以代碼寫起來(lái)簡(jiǎn)單明了
第五步:獲取分頁(yè)下圖片所指url
通過(guò)檢查涛碑,可以看到獲取到的url為相對(duì)地址精堕,需要將其轉(zhuǎn)化為絕對(duì)地址
select = 'div#main div.list ul li a'
imgUrls = screen(url, select)
通過(guò)這兩行代碼獲取的列表中的值,形如此:
<a href="/desk/21237.htm" target="_blank" title="星空 女孩 觀望 唯美夜景壁紙 更新時(shí)間:2019-12-06"><img alt="星空 女孩 觀望 唯美夜景壁紙" src="http://img.netbian.com/file/newc/e4f018f89fe9f825753866abafee383f.jpg"/><b>星空 女孩 觀望 唯美夜景壁紙</b></a>
需要對(duì)獲取的列表進(jìn)行處理
獲取a標(biāo)簽中的href屬性值蒲障,并將其轉(zhuǎn)化為絕對(duì)地址歹篓,這是第一次跳轉(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/'): # 過(guò)濾圖片廣告
continue
# 第一次跳轉(zhuǎn)
if('http://' in href): # 有極個(gè)別圖片不提供正確的相對(duì)地址
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 + ' 無(wú)此圖片,爬取失敗')
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)
目錄五:代碼的容錯(cuò)能力
一:過(guò)濾圖片廣告
if(href == 'http://pic.netbian.com/'): # 過(guò)濾圖片廣告
continue
二:第一次跳轉(zhuǎn)頁(yè)面,無(wú)我們需要的鏈接
彼岸壁紙網(wǎng)站余黎,對(duì)第一次跳轉(zhuǎn)頁(yè)面的鏈接重窟,給的都是相對(duì)地址
但是極個(gè)別圖片直接給的絕對(duì)地址,而且給的是該分類網(wǎng)址惧财,所以需要做兩步處理
if('http://' in href):
url = href
else:
url = index + href
...
if(link == []):
print(url + ' 無(wú)此圖片巡扇,爬取失敗')
continue
下面是第二次跳轉(zhuǎn)頁(yè)面所遇問(wèn)題
三:由于權(quán)限問(wèn)題無(wú)法爬取圖片
if(link == []):
print(url + "該圖片需要登錄才能爬取,爬取失敗")
continue
四:獲取img的alt垮衷,作為下載圖片文件的文件名時(shí)厅翔,名字中攜帶\t 或 文件名不允許的特殊字符:
在Python中,’\t’ 是轉(zhuǎn)義字符:空格
在windows系統(tǒng)當(dāng)中的文件命名搀突,文件名稱中不能包含?\ / : * ? " < > |?一共9個(gè)特殊字符
name = link[0].get('alt').replace('\t', '').replace('|', '').replace(':', '').replace('\\', '').replace('/', '').replace('*', '').replace('?', '').replace('"', '').replace('<', '').replace('>', '')
五:獲取img的alt刀闷,作為下載圖片文件的文件名時(shí),名字重復(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
目錄六:完整代碼
藍(lán)奏云鏈接:Python爬蟲(chóng)甸昏,高清美圖我全都要(彼岸桌面壁紙).zip
下載下來(lái)解壓后顽分,有兩個(gè)python文件
最后
動(dòng)動(dòng)你們發(fā)財(cái)?shù)男∈郑o小編一個(gè)關(guān)注就是小編最大的動(dòng)力施蜜,謝謝卒蘸!