这里只是简单介绍主要内容,详见github,仓库地址:hero-skin-images,下面是仓库页面截图,点击图片可直接跳转到仓库。
这个项目还是比较简单的,因为很多数据都已经json数据中,我们可以很方便的从中取出我们想要的数据。至于下载皮肤图片的主要难点是拼接图片URL,这里有个小坑就是:每张图片都有5种(或者说至少是5种)尺寸的图片,我之前就只发现了其中一种,当然你可以有选择的进行下载;尺寸详见:皮肤图片尺寸分析。
使用requests库进行网络连接,获取网址数据。
使用json库解析json文件(数据)。
使用os库创建文件夹。
字符串拼接。
我已经将可能有用的json文件都下载了,并且进行了格式化(转换编码为utf8),放在了./wzry/json数据/
文件夹下。或者你可以到下面提到的链接中取下载对应的文件(访问json文件URL会自动下载)。
英雄列表介绍主页:https://pvp.qq.com/web201605/herolist.shtml,有herolist.json
。
herolist.json
:英雄列表skin_name
这个属性不一定有,比如新英雄可能就没有)。[
{
"ename": 522,
"cname": "曜",
"title": "星辰之子",
"new_type": 0,
"hero_type": 1,
"skin_name": "归虚梦演"
},
{
"ename": 518,
"cname": "马超",
"title": "冷晖之枪",
"new_type": 1,
"hero_type": 1,
"hero_type2": 4
}
]
英雄皮肤图片信息只涉及到 herolist.json
数据,目前发现图片有5种尺寸,注意:下面的图片大小只是对应英雄的图片尺寸,猜测不是固定的,而是在一定范围内变化。
下面以英雄马超为例,英雄首页:https://pvp.qq.com/web201605/herodetail/518.shtml
形式一URL–猜测用于手机端显示 | 猜测用途 | 图片尺寸 |
---|---|---|
https://game.gtimg.cn/images/yxzj/img201606/heroimg/518/518-smallskin-1.jpg | 英雄头像 | 67*67 |
https://game.gtimg.cn/images/yxzj/img201606/heroimg/518/518-mobileskin-1.jpg | 小屏手机英雄背景 | 600*410 |
https://game.gtimg.cn/images/yxzj/img201606/heroimg/518/518-bigskin-1.jpg | 大屏手机英雄背景 | 1200*530 |
形式二URL–猜测是壁纸 | 猜测用途 | 图片尺寸 |
---|---|---|
https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/518/518-mobileskin-1.jpg | 手机壁纸 | 727*1071 |
https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/518/518-bigskin-1.jpg | 电脑壁纸 | 1920*882 |
测试环境:Python3.7.1,JetBrains PyCharm Community Edition 2018.2.4 x64。
依赖:requests
,json
,如果没有安装requests
,用 pip install requests
进行安装即可(json
为内置库)。
使用说明:主程序为:./wzry/wzry.py
,运行该程序会将图片下载在当前目录的五个文件夹内,如./wzry/phone-bigskin-images/
;如需下载全部英雄图片,请将程序中的 break语句
注释掉。
# -*-coding:utf-8 -*-
"""
@author: yansheng
@file: wzry.py
@time: 2019/9/14
"""
# 爬取王者荣耀的英雄皮肤图片
import requests
import json
import os
def mkdirs(path):
"""
辅助函数:创建文件夹
:param path: 文件夹名
:return:
"""
# 去除首末的空格
path = path.strip()
# 去除尾部 \ 符号
path = path.rstrip("\\")
'''
windows下文件名中不能含有:\ / : * ? " < > | 英文的这些字符 ,这里使用"'"、"-"进行替换。
:?| 用-替换
"<> 用'替换
'''
# 对于文件夹,有没有.好像都是同一个文件
# replace方法默认替换所有匹配项
path = path.replace(":", "-").replace("?", "-").replace("|", "-")
path = path.replace("<", "'").replace(">", "'").replace("\"", "'")
# 判断路径是否存在,存在True,不存在False
is_exists = os.path.exists(path)
# 判断结果
if not is_exists:
# 如果不存在则创建目录,这里使用创建多重目录的函数
os.makedirs(path)
print('文件夹\'' + path + '\'创建成功!')
return True
else:
# 如果目录存在则不创建,并提示目录已存在
print('文件夹\'' + path + '\'目录已存在!')
return False
def downloadImages():
"""
主要的函数:获取王者荣耀图片信息,下载图片
"""
'''
1.按照分析,创建对应文件夹
1.1.https://game.gtimg.cn/images/yxzj/img201606/heroimg/518/518-smallskin-1.jpg
phone-smallskin-images 头像
phone-mobileskin-images 小屏手机图片
phone-bigskin-images 大屏手机图片
1.2.https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/518/518-mobileskin-1.jpg
wallpaper-mobileskin-images 手机壁纸
wallpaper-bigskin-images 电脑壁纸
1.3. 观察url变化情况
类型1:
李白的第二个皮肤:https://game.gtimg.cn/images/yxzj/img201606/heroimg/131/131-bigskin-2.jpg
孙悟空的第二个皮肤:https://game.gtimg.cn/images/yxzj/img201606/heroimg/167/167-bigskin-2.jpg
类型2:
https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/518/518-mobileskin-1.jpg
不同之处:131/131-bigskin-2
'''
# 定义变量
prefix_url1 = 'https://game.gtimg.cn/images/yxzj/img201606/heroimg/'
prefix_url2 = 'https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/'
suffix_url = '.jpg'
smallskin = '-smallskin-'
mobileskin = '-mobileskin-'
bigskin = '-bigskin-'
phone_smallskin_dirpath = 'phone-smallskin-images'
phone_mobileskin_dirpath = 'phone-mobileskin-images'
phone_bigskin_dirpath = 'phone-bigskin-images'
wallpaper_mobileskin_dirpath = 'wallpaper-mobileskin-images'
wallpaper_bigskin_dirpath = 'wallpaper-bigskin-images'
# 创建目录
mkdirs(phone_smallskin_dirpath)
mkdirs(phone_mobileskin_dirpath)
mkdirs(phone_bigskin_dirpath)
mkdirs(wallpaper_mobileskin_dirpath)
mkdirs(wallpaper_bigskin_dirpath)
# 2.获取英雄列表的json数据
json_url = 'https://pvp.qq.com/web201605/js/herolist.json' # 英雄的列表信息
r = requests.get(json_url).text # json数据--字符串
# print(r)
result = json.loads(r) # 把字符串转换成字典,这里是由88个字典组成的list
print('王者荣耀的英雄个数:%d' % len(result)) # 王者荣耀的英雄个数:88
# 循环读取json数据,获得英雄对应数据,拼接图片url,下载图片
for i in result:
id = i['ename'] # 英雄id
cname = i['cname'] # 英雄名
title = i['title'] # 默认皮肤,即第一个皮肤
# 判断该英雄是否有skin_name属性(新英雄可能会没有),有就取值,没有就直接将列表置为空
skin_name_lists = []
if 'skin_name' in i.keys():
skin_name = i['skin_name'] # 皮肤名
skin_name_lists = skin_name.split('|') # 把字符串变成列表,用|做分隔符
# 记录英雄的title和skin_name的第一个属性不一样的英雄的id
diff_ids = [109, 113, 176]
if id in diff_ids:
skins_lists = [title] + skin_name_lists[1:]
else:
skins_lists = [title] + skin_name_lists
else:
skins_lists = [title]
# 将title 和skin_name_lists合并为列表,然后转为集合,自动去重,
# 同时保证顺序不变,因为需要设置第一个为伴生皮肤
skins_set_lists = list(set(skins_lists))
skins_set_lists.sort(key=skins_lists.index)
# 拼接网址
for skin in skins_set_lists:
# 获取下标,作为英雄皮肤数量
index = skins_set_lists.index(skin) + 1
# skin_name_lists.index(skin_name_list)为列表的下标
# https://game.gtimg.cn/images/yxzj/img201606/heroimg/ + 105 + '/ '+ 105 + '-smallskin-' + 1 + '.jpg'
# 类型1
mid_url = '%d' % id + '/' + '%d' % id
phone_smallskin_url = prefix_url1 + mid_url + smallskin + '%d' % index + suffix_url
phone_mobileskin_url = prefix_url1 + mid_url + mobileskin + '%d' % index + suffix_url
phone_bigskin_url = prefix_url1 + mid_url + bigskin + '%d' % index + suffix_url
# 类型2
wallpaper_mobileskin_url = prefix_url2 + mid_url + mobileskin + '%d' % index + suffix_url
wallpaper_bigskin_url = prefix_url2 + mid_url + bigskin + '%d' % index + suffix_url
# 为方便起见,将对于类型的图片的文件夹和图片url组成 一对字典:
url_dict = {
phone_smallskin_dirpath: phone_smallskin_url,
phone_mobileskin_dirpath: phone_mobileskin_url,
phone_bigskin_dirpath: phone_bigskin_url,
wallpaper_mobileskin_dirpath: wallpaper_mobileskin_url,
wallpaper_bigskin_dirpath: wallpaper_bigskin_url,
}
# 遍历字典,取出对应键值,键:图片保存的目录,值:图片网址
for dirpath in url_dict:
# 定义保存到本地的图片名称,如:廉颇-1-正义爆轰.jpg
image_path = dirpath + '/%s-%d-%s.jpg' % (cname, index, skin)
# print("图片文件名:" + image_path)
# 将判断放到前面,进行优化
# 判断文件(图片)是否存在,如果存在就不重复下载,不存在就下载
if os.path.exists(image_path):
print(' ' + image_path + '图片已存在!')
continue
# 获取图片的网址,如果返回状态码为200,下载图片
img_url = url_dict[dirpath]
if requests.get(img_url).status_code == 200:
print('图片地址:' + img_url)
img = requests.get(img_url)
# 以二进制形式写文件(下载图片)
with open(image_path, 'wb') as f:
f.write(img.content) # 写入图片的二进制数据
print(' ' + image_path + '下载成功!')
# 测试时,只下载一个英雄的皮肤图片;如需下载所有英雄的皮肤图片,请注释下面的break
break
if __name__ == '__main__':
downloadImages()
print('\n**王者荣耀全部英雄皮肤图片已下载成功**')
注:因为该程序是解析json文件获得对应英雄的信息,但是仔细观察后,发现该数据稍有滞后,有部分数据还未进行更新;故该数据非最新数据,仅供参考。(如需要获得最新数据就需要爬取网页元素进行分析,有兴趣者可自行扩展)
1.该文件夹包含了王者荣耀所有英雄的皮肤图片,有5种尺寸。
2.数据汇总(截止:2019年9月14日19:39:23)
英雄数量:95个
皮肤数量:338个(含伴生皮肤)3.图片尺寸说明(图片尺寸和大小应该是在一定范围内变化,不是定值,以下数据仅供参考):
文件夹 每张图片尺寸(像素) 图片大小(KB) 说明(猜测) phone-smallskin-images/ 67*67 20 英雄头像 phone-mobileskin-images/ 600*410 200 小屏手机英雄背景 phone-bigskin-images/ 1200*530 450 大屏手机英雄背景 wallpaper-mobileskin-images/ 727*1071 530 手机壁纸 wallpaper-bigskin-images/ 1920*882 900 电脑壁纸 4.文件夹大小
文件夹 文件夹大小(MB) phone-smallskin-images/ 2 phone-mobileskin-images/ 34.6 phone-bigskin-images/ 68 wallpaper-mobileskin-images/ 61 wallpaper-bigskin-images/ 105
我已将图片全部都下载了,并上传到百度云,有需要可自取。
百度云链接:
链接:https://pan.baidu.com/s/1uFGfSPuKBzYJjEjn6YCx-A
提取码:fd3t
或者扫描下面的二维码
本项目仅用于学习交流使用,禁止进行商业目的的开发、发布、运营等。数据所有权归 腾讯公司 所有。