如何通过爬虫实战(七)高效获取王者荣耀英雄图片?

2026-04-11 07:441阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2100个文字,预计阅读时间需要9分钟。

如何通过爬虫实战(七)高效获取王者荣耀英雄图片?

目录+爬虫实战(七):爬虫英雄图片+网站分析+页面分析+源码分析+链接分析+爬取过程+编写代码+获取JSON数据+获取皮肤数量+下载皮肤图片

目录
  • 爬虫实战(七):爬王者英雄图片
    • 一、 网站分析
      • 1、 页面分析
      • 2、 源码分析
      • 3、 链接分析
      • 4、 爬取过程
    • 二、 编写代码
      • 1、 获取JSON数据
      • 2、 获取皮肤数量
      • 3、 下载皮肤图片
    • 三、 总代码

爬虫实战(七):爬王者英雄图片 一、 网站分析 1、 页面分析

我们对王者荣耀英雄界面分析,发现,其数据并不是存储在源码中的,那么其不是静态网址,我们不能通过直接获取源码来获取数据

通过F12抓包可以得到一个和页面链接同名的json文件,里面存储了许多的乱码信息,通过编码utf-8,可以看出,这个JSON存储的正是所有英雄的信息

如何通过爬虫实战(七)高效获取王者荣耀英雄图片?

2、 源码分析

那么,我们的主页面分析完了,然后,我们分析单独英雄的界面,我们发现每个英雄的界面中的背景图片就是英雄的高清大图,并且可以通过右下角的图标来切换图片,那么,图片链接就一定存储在页面的源码中,果然,通过翻译我们找到了背景图片的链接,我们可以推测,如果把图片的链接最后一个数字改为2,就可以换到第二个皮肤,那么,我们如何获取皮肤数量呢?

3、 链接分析

那么,问题来了,我们如何进入每个英雄的详情界面呢?

这里,我们先展示一下我们先前获取的部分的英雄数据

[{'ename': 105, 'cname': '廉颇', 'title': '正义爆轰', 'new_type': 0, 'hero_type': 3, 'skin_name': '正义爆轰|地狱岩魂'}, {'ename': 106, 'cname': '小乔', 'title': '恋之微风', 'new_type': 0, 'hero_type': 2, 'skin_name': '恋之微风|万圣前夜|天鹅之梦|纯白花嫁|缤纷独角兽'}, {'ename': 107, 'cname': '赵云', 'title': '苍天翔龙', 'new_type': 0, 'hero_type': 1, 'hero_type2': 4, 'skin_name': '苍天翔龙|忍●炎影|未来纪元|皇家上将|嘻哈天王|白执事|引擎之心'}]

然后,我们再来看一下详情页的链接

pvp.qq.com/web201605/herodetail/105.shtml 廉颇 pvp.qq.com/web201605/herodetail/106.shtml 小乔 pvp.qq.com/web201605/herodetail/107.shtml 赵云

故,我们发现,数据里面的ename可以帮助我们获取英雄详情页的链接,同时,shin_name为英雄皮肤,但是从廉颇这里可以看出英雄皮肤并不是很全,

那么,我们如何给图片进行命名呢?

从源码中,我们发现,有一个地方存储了英雄的皮肤数据,并且,其和英雄图片的索引也是对应的,我们也可以根据这个来查看有多少个皮肤

那么,能不能再简单一点呢?

我们来直接分析一下英雄原皮的图片链接:

game.gtimg.cn/images/yxzj/img201606/skin/hero-info/105/105-bigskin-1.jpg # 廉颇 game.gtimg.cn/images/yxzj/img201606/skin/hero-info/106/106-bigskin-1.jpg # 小乔 game.gtimg.cn/images/yxzj/img201606/skin/hero-info/107/107-bigskin-1.jpg # 赵云 我们发现,就只有英雄编号的改变,其余内容都是不变的 4、 爬取过程

那么,我们的爬取方式是:

  1. 获取全部的英雄数据
  2. 获取英雄有多少个皮肤
  3. 对图片发送请求
二、 编写代码 1、 获取JSON数据

import requests # 导入模块,发送请求,处理JSON数据 from fake_useragent import UserAgent # 随机请求头 headers = { "user-agent": UserAgent().random, # 请求头 "referer": "pvp.qq.com/web201605/herolist.shtml", # 表明来源 } infolist = [] def get_infolist(): resp = requests.get("pvp.qq.com/web201605/js/herolist.json", headers=headers) # 发送请求 resp.encoding = resp.apparent_encoding # 设置编码,防止出现乱码 data = resp.json() # 获取数据,并转换为列表格式 for i in data: """我们只取英雄编号和英雄名称""" infolist.append({ "id": i["ename"], "name": i["cname"] }) print("英雄数据获取完成!") get_infolist() print(infolist) 2、 获取皮肤数量

import re # 使用正则解析,获取数据 skin_num_url = "pvp.qq.com/web201605/herodetail/%d.shtml" def get_skin_num(id): resp = requests.get(skin_num_url % id, headers=headers) # 发送请求 resp.encoding = resp.apparent_encoding # 设置编码,防止出现乱码 skin = re.search('<ul class="pic-pf-list.*?" data-imgname="(?P<skin>.*?)">', resp.text).group("skin") # 清洗数据 lis = skin.split("|") # print(lis) for k, i in enumerate(lis): try: temp = re.search("(?P<name>.*?)&", i).group("name") except AttributeError: temp = i # 可能不需要对数据进行清洗 lis[k] = temp # print(lis) return lis # get_skin_num(105) for i in infolist: """遍历数据,向字典中加入皮肤名字和皮肤数量""" ret = get_skin_num(i["id"]) # 把id传入 i.update({ "skin": ret, }) print(infolist) 3、 下载皮肤图片

import os, time skin_url = "game.gtimg.cn/images/yxzj/img201606/skin/hero-info/{id}/{id}-bigskin-{index}.jpg" def save_skin(dic): """把数据字典传入,进行其余的操作""" if not os.path.exists(f"./王者荣耀皮肤/{dic['name']}"): os.mkdir(f"./王者荣耀皮肤/{dic['name']}") for i in range(len(dic["skin"])): url_ = skin_url.format(id=dic["id"], index=i + 1) resp = requests.get(url_, headers=headers) file = open(f"./王者荣耀皮肤/{dic['name']}/{dic['skin'][i]}.jpg", "wb") file.write(resp.content) file.close() print(dic["skin"][i], "下载完成") time.sleep(30) for i in infolist: save_skin(i) print(f"{i['name']}英雄皮肤下载完成") print("所有皮肤下载完成!") 三、 总代码

import requests # 导入模块,发送请求 import re # 使用正则解析,获取数据 import os, time, json # 将数据写入文件中 from fake_useragent import UserAgent # 随机请求头 headers = { "user-agent": UserAgent().random, # 请求头 "referer": "pvp.qq.com/web201605/herolist.shtml", # 表明来源 } skin_num_url = "pvp.qq.com/web201605/herodetail/%d.shtml" skin_url = "game.gtimg.cn/images/yxzj/img201606/skin/hero-info/{id}/{id}-bigskin-{index}.jpg" infolist = [] def get_infolist(): global infolist try: with open("infolist.json", "r", encoding="utf-8") as file: infolist = json.load(file) if not infolist: # 如果文件里面没有值直接报错 raise IOError except Exception as e: resp = requests.get("pvp.qq.com/web201605/js/herolist.json", headers=headers) # 发送请求 resp.encoding = resp.apparent_encoding # 设置编码,防止出现乱码 data = resp.json() # 获取数据,并转换为列表格式 for i in data: """我们只取英雄编号和英雄名称""" infolist.append({ "id": i["ename"], "name": i["cname"] }) print("英雄数据获取完成!") def get_skin_num(id): """获取皮肤名字和数量""" resp = requests.get(skin_num_url % id, headers=headers) # 发送请求 resp.encoding = resp.apparent_encoding # 设置编码,防止出现乱码 skin = re.search('<ul class="pic-pf-list.*?" data-imgname="(?P<skin>.*?)">', resp.text).group("skin") # 清洗数据 lis = skin.split("|") # print(lis) for k, i in enumerate(lis): try: temp = re.search("(?P<name>.*?)&", i).group("name") except AttributeError: temp = i # 可能不需要对数据进行清洗 lis[k] = temp # print(lis) return lis def save_skin(dic): """把数据字典传入,进行其余的操作""" if not os.path.exists(f"./王者荣耀皮肤/{dic['name']}"): os.mkdir(f"./王者荣耀皮肤/{dic['name']}") for i in range(len(dic["skin"])): url_ = skin_url.format(id=dic["id"], index=i + 1) resp = requests.get(url_, headers=headers) file = open(f"./王者荣耀皮肤/{dic['name']}/{dic['skin'][i]}.jpg", "wb") file.write(resp.content) file.close() print(dic["skin"][i], "下载完成") time.sleep(30) def main(): get_infolist() if not os.path.exists(f"./王者荣耀皮肤"): """如果文件夹不存在,则创建""" os.mkdir(f"./王者荣耀皮肤") for i in infolist: """遍历数据,向字典中加入皮肤名字和皮肤数量""" ret = get_skin_num(i["id"]) # 把id传入 i.update({ "skin": ret, "is_down": False # 记录是否已经下载 }) # 将数据写入文件中,下次可以继续使用 file = open("infolist.json", "w", encoding="utf-8") json.dump(infolist, file, indent=8, ensure_ascii=False) file.close() for i in infolist: if not i["is_down"]: # 如果皮肤没有下载,则下载 save_skin(i) print(f"{i['name']}英雄皮肤下载完成") i["is_down"] = True else: print(f"{i['name']}英雄皮肤已经下载") print("所有皮肤下载完成!") if __name__ == "__main__": main()

最后,尽情欣赏图片吧!

本文共计2100个文字,预计阅读时间需要9分钟。

如何通过爬虫实战(七)高效获取王者荣耀英雄图片?

目录+爬虫实战(七):爬虫英雄图片+网站分析+页面分析+源码分析+链接分析+爬取过程+编写代码+获取JSON数据+获取皮肤数量+下载皮肤图片

目录
  • 爬虫实战(七):爬王者英雄图片
    • 一、 网站分析
      • 1、 页面分析
      • 2、 源码分析
      • 3、 链接分析
      • 4、 爬取过程
    • 二、 编写代码
      • 1、 获取JSON数据
      • 2、 获取皮肤数量
      • 3、 下载皮肤图片
    • 三、 总代码

爬虫实战(七):爬王者英雄图片 一、 网站分析 1、 页面分析

我们对王者荣耀英雄界面分析,发现,其数据并不是存储在源码中的,那么其不是静态网址,我们不能通过直接获取源码来获取数据

通过F12抓包可以得到一个和页面链接同名的json文件,里面存储了许多的乱码信息,通过编码utf-8,可以看出,这个JSON存储的正是所有英雄的信息

如何通过爬虫实战(七)高效获取王者荣耀英雄图片?

2、 源码分析

那么,我们的主页面分析完了,然后,我们分析单独英雄的界面,我们发现每个英雄的界面中的背景图片就是英雄的高清大图,并且可以通过右下角的图标来切换图片,那么,图片链接就一定存储在页面的源码中,果然,通过翻译我们找到了背景图片的链接,我们可以推测,如果把图片的链接最后一个数字改为2,就可以换到第二个皮肤,那么,我们如何获取皮肤数量呢?

3、 链接分析

那么,问题来了,我们如何进入每个英雄的详情界面呢?

这里,我们先展示一下我们先前获取的部分的英雄数据

[{'ename': 105, 'cname': '廉颇', 'title': '正义爆轰', 'new_type': 0, 'hero_type': 3, 'skin_name': '正义爆轰|地狱岩魂'}, {'ename': 106, 'cname': '小乔', 'title': '恋之微风', 'new_type': 0, 'hero_type': 2, 'skin_name': '恋之微风|万圣前夜|天鹅之梦|纯白花嫁|缤纷独角兽'}, {'ename': 107, 'cname': '赵云', 'title': '苍天翔龙', 'new_type': 0, 'hero_type': 1, 'hero_type2': 4, 'skin_name': '苍天翔龙|忍●炎影|未来纪元|皇家上将|嘻哈天王|白执事|引擎之心'}]

然后,我们再来看一下详情页的链接

pvp.qq.com/web201605/herodetail/105.shtml 廉颇 pvp.qq.com/web201605/herodetail/106.shtml 小乔 pvp.qq.com/web201605/herodetail/107.shtml 赵云

故,我们发现,数据里面的ename可以帮助我们获取英雄详情页的链接,同时,shin_name为英雄皮肤,但是从廉颇这里可以看出英雄皮肤并不是很全,

那么,我们如何给图片进行命名呢?

从源码中,我们发现,有一个地方存储了英雄的皮肤数据,并且,其和英雄图片的索引也是对应的,我们也可以根据这个来查看有多少个皮肤

那么,能不能再简单一点呢?

我们来直接分析一下英雄原皮的图片链接:

game.gtimg.cn/images/yxzj/img201606/skin/hero-info/105/105-bigskin-1.jpg # 廉颇 game.gtimg.cn/images/yxzj/img201606/skin/hero-info/106/106-bigskin-1.jpg # 小乔 game.gtimg.cn/images/yxzj/img201606/skin/hero-info/107/107-bigskin-1.jpg # 赵云 我们发现,就只有英雄编号的改变,其余内容都是不变的 4、 爬取过程

那么,我们的爬取方式是:

  1. 获取全部的英雄数据
  2. 获取英雄有多少个皮肤
  3. 对图片发送请求
二、 编写代码 1、 获取JSON数据

import requests # 导入模块,发送请求,处理JSON数据 from fake_useragent import UserAgent # 随机请求头 headers = { "user-agent": UserAgent().random, # 请求头 "referer": "pvp.qq.com/web201605/herolist.shtml", # 表明来源 } infolist = [] def get_infolist(): resp = requests.get("pvp.qq.com/web201605/js/herolist.json", headers=headers) # 发送请求 resp.encoding = resp.apparent_encoding # 设置编码,防止出现乱码 data = resp.json() # 获取数据,并转换为列表格式 for i in data: """我们只取英雄编号和英雄名称""" infolist.append({ "id": i["ename"], "name": i["cname"] }) print("英雄数据获取完成!") get_infolist() print(infolist) 2、 获取皮肤数量

import re # 使用正则解析,获取数据 skin_num_url = "pvp.qq.com/web201605/herodetail/%d.shtml" def get_skin_num(id): resp = requests.get(skin_num_url % id, headers=headers) # 发送请求 resp.encoding = resp.apparent_encoding # 设置编码,防止出现乱码 skin = re.search('<ul class="pic-pf-list.*?" data-imgname="(?P<skin>.*?)">', resp.text).group("skin") # 清洗数据 lis = skin.split("|") # print(lis) for k, i in enumerate(lis): try: temp = re.search("(?P<name>.*?)&", i).group("name") except AttributeError: temp = i # 可能不需要对数据进行清洗 lis[k] = temp # print(lis) return lis # get_skin_num(105) for i in infolist: """遍历数据,向字典中加入皮肤名字和皮肤数量""" ret = get_skin_num(i["id"]) # 把id传入 i.update({ "skin": ret, }) print(infolist) 3、 下载皮肤图片

import os, time skin_url = "game.gtimg.cn/images/yxzj/img201606/skin/hero-info/{id}/{id}-bigskin-{index}.jpg" def save_skin(dic): """把数据字典传入,进行其余的操作""" if not os.path.exists(f"./王者荣耀皮肤/{dic['name']}"): os.mkdir(f"./王者荣耀皮肤/{dic['name']}") for i in range(len(dic["skin"])): url_ = skin_url.format(id=dic["id"], index=i + 1) resp = requests.get(url_, headers=headers) file = open(f"./王者荣耀皮肤/{dic['name']}/{dic['skin'][i]}.jpg", "wb") file.write(resp.content) file.close() print(dic["skin"][i], "下载完成") time.sleep(30) for i in infolist: save_skin(i) print(f"{i['name']}英雄皮肤下载完成") print("所有皮肤下载完成!") 三、 总代码

import requests # 导入模块,发送请求 import re # 使用正则解析,获取数据 import os, time, json # 将数据写入文件中 from fake_useragent import UserAgent # 随机请求头 headers = { "user-agent": UserAgent().random, # 请求头 "referer": "pvp.qq.com/web201605/herolist.shtml", # 表明来源 } skin_num_url = "pvp.qq.com/web201605/herodetail/%d.shtml" skin_url = "game.gtimg.cn/images/yxzj/img201606/skin/hero-info/{id}/{id}-bigskin-{index}.jpg" infolist = [] def get_infolist(): global infolist try: with open("infolist.json", "r", encoding="utf-8") as file: infolist = json.load(file) if not infolist: # 如果文件里面没有值直接报错 raise IOError except Exception as e: resp = requests.get("pvp.qq.com/web201605/js/herolist.json", headers=headers) # 发送请求 resp.encoding = resp.apparent_encoding # 设置编码,防止出现乱码 data = resp.json() # 获取数据,并转换为列表格式 for i in data: """我们只取英雄编号和英雄名称""" infolist.append({ "id": i["ename"], "name": i["cname"] }) print("英雄数据获取完成!") def get_skin_num(id): """获取皮肤名字和数量""" resp = requests.get(skin_num_url % id, headers=headers) # 发送请求 resp.encoding = resp.apparent_encoding # 设置编码,防止出现乱码 skin = re.search('<ul class="pic-pf-list.*?" data-imgname="(?P<skin>.*?)">', resp.text).group("skin") # 清洗数据 lis = skin.split("|") # print(lis) for k, i in enumerate(lis): try: temp = re.search("(?P<name>.*?)&", i).group("name") except AttributeError: temp = i # 可能不需要对数据进行清洗 lis[k] = temp # print(lis) return lis def save_skin(dic): """把数据字典传入,进行其余的操作""" if not os.path.exists(f"./王者荣耀皮肤/{dic['name']}"): os.mkdir(f"./王者荣耀皮肤/{dic['name']}") for i in range(len(dic["skin"])): url_ = skin_url.format(id=dic["id"], index=i + 1) resp = requests.get(url_, headers=headers) file = open(f"./王者荣耀皮肤/{dic['name']}/{dic['skin'][i]}.jpg", "wb") file.write(resp.content) file.close() print(dic["skin"][i], "下载完成") time.sleep(30) def main(): get_infolist() if not os.path.exists(f"./王者荣耀皮肤"): """如果文件夹不存在,则创建""" os.mkdir(f"./王者荣耀皮肤") for i in infolist: """遍历数据,向字典中加入皮肤名字和皮肤数量""" ret = get_skin_num(i["id"]) # 把id传入 i.update({ "skin": ret, "is_down": False # 记录是否已经下载 }) # 将数据写入文件中,下次可以继续使用 file = open("infolist.json", "w", encoding="utf-8") json.dump(infolist, file, indent=8, ensure_ascii=False) file.close() for i in infolist: if not i["is_down"]: # 如果皮肤没有下载,则下载 save_skin(i) print(f"{i['name']}英雄皮肤下载完成") i["is_down"] = True else: print(f"{i['name']}英雄皮肤已经下载") print("所有皮肤下载完成!") if __name__ == "__main__": main()

最后,尽情欣赏图片吧!