Python爬取LOL高清皮肤壁纸
兴趣点:
这两天复习爬虫,CSDN上看到了一个爬取LOL皮肤的博客,哎这个有意思,看了一下他写的代码,感觉难度还可以,就结合着自己的理解写了一下
参考博客:
传送门:https://blog.csdn.net/weixin_44936889/article/details/103707406
爬取网址:
传送门:http://lol.52pk.com/pifu/hero/
爬虫大体思路及方法:
大体思路:
(1)我们的目标网页共43页,每页有25个皮肤左右,点开是皮肤大图及相关内容,其中的大图链接就是我们的目标
(2)我们要先把大约43×25个皮肤大图展示页面的链接先爬出来放到一个列表中
(3)再根据列表中的链接采用循环的方法获取其中的“英雄名-皮肤名”和皮肤图片链接,并将其一对一写入一个列表
(4)按顺序爬取列表中图片链接对应的图片并输出对应的提示信息
方法:
(1)页面获取方法:getHTMLText(url)
(2)把所有皮肤页URL写入列表:fillList(skinlist,url)
(3)获取皮肤命名和图片URL:getImageAddress(skinlist,nameAndImage)
(4)图片下载及保存:getImage(path,nameAndImage)
参数解读:
(1)skinlist——保存所有皮肤页面链接的列表
(2)nameAndImage——保存皮肤命名和皮肤图片链接的列表
(3)path——本地保存路径
部分细节讲解:
(1)观察网页原代码,找到页面的规律:
我们可以得知页面的真实地址,页面数43页和规律,所以后面的代码是这么写:
for i in range(1, 44): #皮肤展示页面共43页
new_url = url + "hero_{}.shtml".format(i) #拼出每个页面url
这里我是为了展示,其实没必要爬43页,毕竟Python运行速度太慢了
(2)目标网页可以识别Request请求,需要伪装成浏览器
kv = {"user-agent":"Mozilla/5.0"}
r = requests.get(url,headers = kv)
(3)从页面中获取到的文本尽量用 .strip() 方法去除两端空格
name = hero_name.strip() + '-' + skin_name.strip()
(4)踩坑记录:因为阿狸的KD/A皮肤文本里有一个”/“,所以会造成找不到路径的错误,替换成空即可
name = name.replace('/', '')
(5)踩坑记录:关于 url 变量,在循环中不要写出下面这样的代码,url会变!url会变!url会变!
url = url + "hero_{}.shtml".format(i)
(6)Python标准异常:
菜鸟教程:https://www.runoob.com/python/python-exceptions.html
(7)关于打印进程提示信息:
有些同学可能认为这个没什么用,但这个很有用:一来可以提示程序运行的进度(Python运行实在是慢),二来可以用来差错,当断点使用
完整代码:
import requests
import re
import os
from bs4 import BeautifulSoup
def getHTMLText(url):
try:
kv = {"user-agent":"Mozilla/5.0"}
r = requests.get(url,headers = kv)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
print("getHTMLText失败!")
return ""
def fillList(skinlist,url):
for i in range(1, 4): #皮肤展示页面共43页
new_url = url + "hero_{}.shtml".format(i) #拼出每个页面url
html = getHTMLText(new_url)
soup = BeautifulSoup(html, features = 'html.parser')
div_soup = soup.find('div', class_ = 'ListBigContent')
lis = div_soup('li') #查询li标签
for li in lis:
skin_url = li.find('a', target='_blank')
skin_url = skin_url.get("href")
skinlist.append(skin_url)
print("页面{0}解读完毕!".format(i))
def getImageAddress(skinlist,nameAndImage):
for url in skinlist:
html = getHTMLText(url)
soup = BeautifulSoup(html, features = 'html.parser')
name_div = soup.find('div', class_ = 'pifuIntroText pifuIntroText2')
hero_name = name_div.find('h2').text
skin_name = name_div.find('h1').text
name = hero_name.strip() + '-' + skin_name.strip()
name = name.replace('/', '') #把字符中的"/"替换成空,否则会影响路径,都是K/DA的锅
image_div = soup.find('div', class_ = 'pifuIntroPic pifuIntroPic2')
image_url = image_div.find('img')
image_url = image_url.get('src')
nameAndImage.append([name,image_url])
print("{0}链接已获取!".format(name))
def getImage(path,nameAndImage):
try:
if not os.path.exists(path):
os.mkdir(path)
for i in range(len(nameAndImage)):
save_path = os.path.join(path, nameAndImage[i][0]+'.jpg')
url = nameAndImage[i][1]
r = requests.get(url)
if not os.path.exists(save_path):
image = r.content
with open(save_path, 'wb') as f:
f.write(image)
print('{}保存成功!'.format(nameAndImage[i][0]))
else:
print('{}已存在'.format(nameAndImage[i][0]))
except Exception as e:
print('{}保存失败'.format(nameAndImage[i][0]),e)
def main():
skinlist = []
nameAndImage =[]
path = "./image"
url = "http://lol.52pk.com/pifu/hero/"
fillList(skinlist,url)
print("fillList成功")
getImageAddress(skinlist,nameAndImage)
print("getImageAddress成功")
getImage(path,nameAndImage)
print("getImage成功")
main()