title: 爬蟲日記-一鍵下載****張壁紙-基礎(chǔ)版 彼岸 桌面壁紙 附源碼 可執(zhí)行
tags: ['python','爬蟲','try except','正則表達式']
date: 2021-12-11
categories: "爬蟲日志"
環(huán)境
window10
python3
re
requests
etree
[TOC]
前言
這次來寫一個基礎(chǔ)版的獲取網(wǎng)絡(luò)上公開免費壁紙的爬蟲溢十,采集的網(wǎng)站為 彼岸桌面 范抓,網(wǎng)站打開是這個樣子:
紅色框框中為我們這次的目標锨亏。
分析網(wǎng)站
以第一頁面為例庐完。
通過測試發(fā)現(xiàn),訪問網(wǎng)站不需要特殊的請求頭或者加密字段敦锌,拿到網(wǎng)頁源碼應(yīng)該會比較容易盒发。
打開 彼岸桌面 ,第一頁紅色框框框住的地方總共有20個圖片蒋得,每張圖片又可以通向這張圖片的詳情頁(大圖頁面),進入大圖也可以拿到大圖的url
乒疏,通過目標圖片的url
额衙,使用一定的方法下載圖片下來就可以了。
繼續(xù)分析并寫出相應(yīng)代碼
1 獲取網(wǎng)頁源碼
這個網(wǎng)站的請求不需要特殊的請求頭怕吴,也沒有什么加密窍侧,因此用最簡單的方法去實現(xiàn)就可以,獲取網(wǎng)頁源碼的方法代碼為:
def get_source_code(url):
"""
獲取給定url的網(wǎng)頁源碼
:param url: 要去訪問的url
:return:返回該url網(wǎng)頁源碼,字符串形式
"""
# 構(gòu)造一個普通的請求頭
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',
}
# 發(fā)送請求转绷,拿到數(shù)據(jù)
response = requests.request("GET", url, headers=headers)
# 返回網(wǎng)頁源碼
return response.text
2 獲取圖片 url
2.1 這里先做一定的分析伟件,再嘗試去寫代碼。
正常的思路是:
相對應(yīng)的幾個數(shù)據(jù)
通過這樣的比對议经,我們可以發(fā)現(xiàn)斧账,大圖和小圖的url
貌似有一些聯(lián)系,通過多找?guī)讖垐D片進行比對煞肾,發(fā)現(xiàn)他們之間大概是這樣的關(guān)系:
大圖url
所包含的數(shù)據(jù)信息咧织,小圖全都有,所以我們可以不進入詳情頁籍救,通過對小圖url
進行一定的處理直接得到大圖的url习绢。
okok,接下來開始寫代碼蝙昙。
2.2 通過上次用到的etree
解析網(wǎng)頁毯炮,獲取小圖的url
def get_img_url(text):
_ = etree.HTML(text)
data_list = _.xpath("http://div[@class='list']//a")
for data in data_list:
# 獲取小圖的url
small_pic_url = data.xpath("./img/@src")[0]
2.3 獲取這張圖片獨特的表示代碼pic_id
def get_img_url(text):
_ = etree.HTML(text)
data_list = _.xpath("http://div[@class='list']//a")
small_pic_url = data.xpath("./img/@src")[0]
pic_id = re.search(r"/small(.*?)\.jpg",small_pic_url).groups()[0][:-10]
關(guān)于正則表達式,這次就不展開說了耸黑,有機會單獨整理歸納出來。
這次推薦一個網(wǎng)址 正則表達式 在線測試 篮幢,有一些常用語法介紹大刊,可以測試正則表達式是否正確,寫之前去測一下三椿,還有一些常用語言的代碼生成缺菌,嗯,本菜貓覺得很贊搜锰。
2.4 獲取大圖的url
def get_img_url(text):
_ = etree.HTML(text)
data_list = _.xpath("http://div[@class='list']//a")
for data in data_list:
small_pic_url = data.xpath("./img/@src")[0]
pic_id = re.search(r"/small(.*?)\.jpg",small_pic_url).groups()[0][:-10]
pic_url = re.sub(re.findall("/(small.*?)\.jpg",small_pic_url)[0],pic_id,small_pic_url)
print("小圖地址\t",small_pic_url)
print("大圖地址\t",pic_url)
2.5 問題的出現(xiàn)與解決
上面的步驟是在網(wǎng)頁給出的小圖url
滿足下圖的情況下測才能夠正常運行的伴郁,但是測試發(fā)現(xiàn),頁面上會隨機出現(xiàn)跳到主頁的圖片蛋叼,它并沒有詳情頁焊傅,url
規(guī)則也不滿足上面的正則剂陡,程序也就拿不到大圖的url,并且因此會報錯狐胎,程序無法繼續(xù)下去鸭栖,因此這個地方我們需要進行一定的處理。
解決辦法
可以在正則的時候?qū)Y(jié)果做一個校驗握巢,如果返回的是
None
,那么就放棄這張圖片晕鹊,繼續(xù)下一張圖片的操作,使用if
去編寫程序暴浦;也可以直接做一個異常處理溅话,即
python
的try ... except ...
這里給出異常處理的代碼,如果需要if
的版本歌焦,自己嘗試一下飞几,實在不行評論區(qū)留言一下,摸魚時間會去看一下解決的同规。
def get_img_url(text):
_ = etree.HTML(text)
data_list = _.xpath("http://div[@class='list']//a")
for data in data_list:
print("-" * 100)
try:
small_pic_url = data.xpath("./img/@src")[0]
pic_id = re.search(r"/small(.*?)\.jpg", small_pic_url).groups()[0][:-10]
pic_url = re.sub(re.findall("/(small.*?)\.jpg",small_pic_url)[0],pic_id,small_pic_url)
print("小圖地址\t",small_pic_url)
print("大圖地址\t",pic_url)
except:
print(data.xpath("./img/@src"),"出錯")
當(dāng)然循狰,這里即便是出錯了,也可以判斷一下券勺,這里如果是一張圖片绪钥,即使分辨率不夠,但是也可以湊活湊活直接就當(dāng)作大圖去下載就是了关炼。這里大家隨意就好程腹。
下載圖片
下載圖片和下載網(wǎng)頁源碼其實是一個樣子的,都是通過訪問去吧網(wǎng)頁的數(shù)據(jù)拿下來儒拂,只不過網(wǎng)頁源碼我們是拿到字符串姓氏的數(shù)據(jù)寸潦,方便后米看的處理,而下載圖片我們是要寫到本地社痛,用字符串寫的話那就不是圖片應(yīng)該有的格式了见转,直接體現(xiàn)就是寫到本地的圖片打不開。
下面是一個常規(guī)的用python
的request
去拿數(shù)據(jù)蒜哀,寫圖片的操作斩箫。
需要先在py文件同級目錄建一個名為img
的文件夾
def download_img(img_url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',
}
resp = requests.get(img_url, headers=headers, stream=True)
if resp.status_code == 200:
open('img/' + str(time.time()) + '.jpg', 'wb').write(resp.content) # 將內(nèi)容寫入圖片
print("下載圖片成功")
resp.status_code
為網(wǎng)頁訪問的狀態(tài)碼,一般200為正常訪問撵儿。這邊做了一個判斷乘客,只有正常拿數(shù)據(jù)才會執(zhí)行寫入圖片的操作。
存儲壁紙的位置為同級目錄下的img
文件夾淀歇,文件名直接以時間戳為名易核。
完整源碼
import re
import time
import requests
from lxml import etree
def get_source_code(url):
"""
獲取給定url的網(wǎng)頁源碼
:param url: 要去訪問的url
:return:返回該url網(wǎng)頁源碼,字符串形式
"""
# 構(gòu)造一個普通的請求頭
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',
}
# 發(fā)送請求浪默,拿到數(shù)據(jù)
response = requests.request("GET", url, headers=headers)
# 返回網(wǎng)頁源碼
return response.text
def get_img_url(text):
_ = etree.HTML(text)
data_list = _.xpath("http://div[@class='list']//a")
for data in data_list:
print("-" * 100)
try:
small_pic_url = data.xpath("./img/@src")[0]
pic_id = re.search(r"/small(.*?)\.jpg", small_pic_url).groups()[0][:-10]
pic_url = re.sub(re.findall("/(small.*?)\.jpg", small_pic_url)[0], pic_id, small_pic_url)
print("小圖地址\t", small_pic_url)
print("大圖地址\t", pic_url)
# 下載圖片
download_img(pic_url)
except:
print(data.xpath("./img/@src"), "出錯")
def download_img(img_url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',
}
resp = requests.get(img_url, headers=headers, stream=True)
if resp.status_code == 200:
open('img/' + str(time.time()) + '.jpg', 'wb').write(resp.content) # 將內(nèi)容寫入圖片
print("下載圖片成功")
if __name__ == '__main__':
url = "http://www.netbian.com/index.htm"
source_code = get_source_code(url)
get_img_url(source_code)
運行結(jié)果
寫在最后
這個爬蟲有很多不完善的地方牡直,比如:
暫時只寫了第一頁缀匕,后面沒寫。井氢。弦追。。花竞。劲件。
圖片名最好也采集到,不然看到的結(jié)果都是一串?dāng)?shù)字约急,很奇怪零远。而且把圖片名那下來之后,可以進行一定的分類篩選厌蔽,比如名稱帶美女兩個字的可以單獨放在另外一個文件夾牵辣,巴拉巴拉。奴饮。纬向。。戴卜。逾条。
下載圖片的地方需要手動先建一個img的文件夾,否則報錯投剥。师脂。。雖然很簡單江锨,但是下次改吃警。。啄育。
整個程序基本使用的是順序結(jié)構(gòu)酌心,單線程運行,下載的速度有待提高(多線程)挑豌;
如果要訪問100谒府,1000頁,那程序萬一中間停止了浮毯,又要從頭開始,那不坑爹嘛泰鸡。加上一個歷史功能也是挺有必要的债蓝;
要是真的要采集比較多的數(shù)量,當(dāng)網(wǎng)站發(fā)發(fā)現(xiàn)了我們的異常操作盛龄,經(jīng)常會把我們的ip給拉黑饰迹,所以加一個代理也是很有必要的芳誓;(測試寫了一頁,沒試過直接搞1000頁)
程序的魯棒性啊鸭。锹淌。。
爬蟲僅做學(xué)習(xí)交流使用赠制。
總之這個爬蟲還有很大的優(yōu)化空間赂摆,下次抽點時間完善一下。
實力有限钟些,才疏學(xué)淺烟号,如有錯誤,歡迎指正政恍。
- 我的個人博客 菜貓子小六 - 博客 (codesix.site)
- 我的簡書 菜貓子小六 - 簡書 (jianshu.com)
- 我的CSDN 菜貓子小六 - CSDN