Python爬虫实战 — — Wallhaven壁纸高清原图下载
一、网站分析
目标网址:https://wallhaven.cc/toplist
页面向下滑动,很容易会发现该网站的一些特点:
1.每页壁纸的数量是固定的,为24张
2.在向下滑动过程中,由于加载出其他页数的壁纸,浏览器顶部的网址也会发生改变
二、可行性分析
观察网站结构、反爬机制等,检测是否可以进行爬虫
- 获取单张壁纸的网址:在单张壁纸上右击“检查”,便可以定位到目标网站的超链接网址
即标签a中的属性href的值
—— 测试用例:https://wallhaven.cc/w/pky5mm
- 获取当前壁纸的图像链接:类似于上一步骤,在壁纸上右击“检查”,便可以定位到该图像链接
即标签img中的属性src的值
——测试用例:https://w.wallhaven.cc/full/pk/wallhaven-pky5mm.jpg
- 成功获取图像链接,爬虫可行!
三、代码分析
1.所需第三方库与请求头
import requests
import time
from lxml import etree
headers = {
# 参数UA,用以模拟浏览器向服务器发送请求
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/94.0.4606.61 Safari/537.36 Edg/94.0.992.31',
# 参数cookie,用以登录图片网站,可获取NSFW类型的图片
# 'cookie': '(填入自己的cookie地址)',
}
2.获取当前页的所有壁纸图像链接
def get_urls(__page__):
# 初始化一个空列表,用以存储壁纸的图像链接
src_urls = []
# 根据页码不同,定制不同的URL
base_url = 'https://wallhaven.cc/toplist'
if page == 1:
list_url = base_url
else:
# 根据不同的页面选择添加不同的连接符
list_url = base_url + "?page=" + str(page)
# 获取壁纸集URL的请求对象
list_request = requests.get(url=list_url, headers=headers)
# 根据xpath语法,获取单个壁纸的URL的列表
list_tree = etree.HTML(list_request.text)
list_urls = list_tree.xpath('//a[@class="preview"]/@href')
# 循环该壁纸列表
for img_url in list_urls:
# 获取当前壁纸的图像链接的请求对象
img_request = requests.get(url=img_url, headers=headers)
# 根据xpath语法,获取当前壁纸的图像链接,并添加至src_list中
img_tree = etree.HTML(img_request.text)
j = img_tree.xpath('//img[@id="wallpaper"]/@src')[0]
src_urls.append(j)
return src_urls
3.根据图像链接存储本地
def save_img(__url__):
# 获取传入的参数url的请求对象
request = requests.get(url=url, headers=headers)
# 由于图像链接中包含图像名称的信息,可将图像名称分离出来
name = str(url)[-20:]
# 存储于本地wallhaven文件夹中
with open('./wallhaven/' + name, "wb") as fp:
fp.write(request.content)
fp.close()
4.最终代码
整理之后的代码如下:
import requests
import time
from lxml import etree
headers = {
# 参数UA,用以模拟浏览器向服务器发送请求
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/94.0.4606.61 Safari/537.36 Edg/94.0.992.31',
# 参数cookie,用以登录图片网站,可获取NSFW类型的图片
# 'cookie': '(填入自己的cookie地址)',
}
# 可使用代理ip,防止自身ip被封
# proxy = {'https': 'https://101.200.185.203:16818'}
def get_urls(__page__):
# 初始化一个空列表,用以存储壁纸的图像链接
src_urls = []
# 根据页码不同,定制不同的URL
base_url = 'https://wallhaven.cc/toplist'
if page == 1:
list_url = base_url
else:
# 根据不同的页面选择添加不同的连接符
list_url = base_url + "?page=" + str(page)
# 获取壁纸集URL的请求对象
list_request = requests.get(url=list_url, headers=headers)
# 根据xpath语法,获取单个壁纸的URL的列表
list_tree = etree.HTML(list_request.text)
list_urls = list_tree.xpath('//a[@class="preview"]/@href')
# 循环该壁纸列表
for img_url in list_urls:
# 获取当前壁纸的图像链接的请求对象
img_request = requests.get(url=img_url, headers=headers)
# 根据xpath语法,获取当前壁纸的图像链接,并添加至src_list中
img_tree = etree.HTML(img_request.text)
j = img_tree.xpath('//img[@id="wallpaper"]/@src')[0]
src_urls.append(j)
return src_urls
def save_img(__url__):
# 获取传入的参数url的请求对象
request = requests.get(url=url, headers=headers)
# 由于图像链接中包含图像名称的信息,可将图像名称分离出来
name = str(url)[-20:]
# 存储于本地wallhaven文件夹中
with open('./wallhaven/' + name, "wb") as fp:
fp.write(request.content)
fp.close()
if __name__ == '__main__':
# 获取起始页码与结束页码
start_page = int(input('Please input the starting page:'))
end_page = int(input('Please input the ending page:'))
print('Start the download...')
for page in range(start_page, end_page + 1):
# 获取单个壁纸的图像链接
for url in get_urls(page):
print(url)
# 将该壁纸存储本地
save_img(url)
# 每存储一张图片,休眠10秒
# time.sleep(10)
# 每存储一页图片,休眠15秒
# time.sleep(15)
print('The download has completed.')
四、个人建议
- 采用代理或者代理池,不仅提高爬取速率,也能尽量保证自身IP地址安全
- 当仅用一个代理或者自身IP访问时,间隔的休眠时间是必要的,否则会报异常
- 注意爬取页面的连接符,有的是"?“有的是”&"
- 登录wallhaven网站后,可以看到NSFW类型的壁纸
- 不使用cookie参数时,只能下载SFW类型的壁纸;使用cookie参数时,可以下载所有类型的壁纸
如何获取cookie参数 ?
在登录账号的情况下,右击“检查”,选择network,在响应列表里查找带cookie参数的,(如果响应列表为空,点击刷新即可)将cookie的值复制过来,以字典的形式保存在headers中
五、结果检验
确实很妙!嘿嘿,全是高清壁纸嗷~
注:有可能会出现壁纸只下了上半截的情况,这是由于网速不够 →_→