Github项目地址 https://github.com/xylon666/Xylon_Code

爬取结果展示: 全原画+皮肤名称分类

 

所需环境

IDE:Pycharm

第三方库:requests,PIL

浏览器:Chrome

爬取目标:

LOL官网皮肤原画 https://lol.qq.com/data/info-heros.shtml#Navi

一、分析页面

与常规的静态网页不同,LOL官网是借由JavaScript脚本在客户端执行后才会展示完整页面的动态网页,直接使用requests请求获得的页面是没有英雄信息的,因此我们要采取一定的方案

鼠标右键原画检查页面,可以看到皮肤原画地址就在眼前

展开后发现原画的地址格为://ossweb-img.qq.com/images/lol/web201310/skin/big+皮肤ID+.jpg

那么我们就要考虑如何获取所有英雄的皮肤ID以及相关信息了

回到全部英雄页面,F12检查元素-Network-JS,找到一个champion.js文件,里面包含全部英雄的id和英文名
可以看到266就是剑魔的ID

当然,最终要有英雄中文名称和皮肤名称,光有id和英文名是不够的

再进入剑魔页面,检查元素,可以找到Aatrox.js

在网页中打开,可以看到剑魔的个人信息,id、英文名、中文名(Unicode编码)、称号、皮肤编号以及名称一应俱全

注意到页面地址为:https://lol.qq.com/biz/hero/Aatrox.js 

也就是说,通过 "https://lol.qq.com/biz/hero/"+英雄英文名+".js" 我们可以访问任何一个英雄的全部信息,进而获取原画链接和名称将其下载下来

所以爬取思路就是:

1.获取champion.js里英雄的英文名称信息

2.访问"https://lol.qq.com/biz/hero/"+英雄英文名+".js",获得英雄具体信息

3.访问"//ossweb-img.qq.com/images/lol/web201310/skin/big"+皮肤ID+".jpg"下载原画

那么,开始写代码吧

二、获取英文名称

下载champion.js至本地

#encoding = 'utf-8'
import requests,json,os
from PIL import Image
from io import BytesIO

url = 'https://lol.qq.com/biz/hero/champion.js'
headers = {
    "user-agent":"Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36",
}
res = requests.get(url,headers = headers )
res.encoding = 'gbk'
html = res.text
print(html)

 

出去开头部分,剩下的就是字典类型,为了方便操作,我们将其处理为json类型

data = json.loads("{"+res.text.strip("if(!LOLherojs)var LOLherojs={};LOLherojs.champion=")+"}")
#删去开头部分
print(data)

通过字典查询可以方便快捷地提取英文名,以及中文名称,英文名进行下一步提取英雄完整信息,中文名称用于创建原画文件夹以及文件名

hero_names = data.get("data").keys()
print(hero_names)
heroid_list = []
hero_cnnames = []
for hero_name in hero_names:
    heroid_list.append(hero_name)
#print(heroid_list)
for heroid in heroid_list:
    #print(heroid)
    first_name = data.get("data").get(heroid).get("name")
    second_name = data.get("data").get(heroid).get("title")
    hero_cnname = first_name + " " + second_name
    hero_cnnames.append(hero_cnname)
print(hero_cnnames)

 三、获取皮肤ID

有了英文名,我们可以访问"https://lol.qq.com/biz/hero/"+英雄英文名+".js"来获取皮肤ID和名称

for i in range(len(heroid_list)):
    id = heroid_list[i]
    hero_url = 'https://lol.qq.com/biz/hero/' + id + '.js'
    res = requests.get(hero_url, headers=headers)
    data = json.loads("{" + res.text.strip("if(!LOLherojs)var LOLherojs={champion:{}};LOLherojs.champion." + id + "=") + "}")
    # print(data)
    skins = data.get("data").get("skins")
    skin_ids = []
    skin_names = []
    skin_urls = []
    for skin in skins:
        skin_names.append(skin.get("name"))
        skin_ids.append(skin.get("id"))
    skin_names[0] = hero_cnnames[i]  # 将默认皮肤default的名称改为英雄名称
    #print(skin_names)

四、下载原画

从列表skin_ids中获取皮肤ID,组合原画地址再下载

自己在尝试下载的时候,发现K/DA系列一直下载失败,原来是 / 符号影响了文件路径的创建,所以加了一条try把斜杠删掉

for skin_id in skin_ids:
    skin_url = "https://ossweb-img.qq.com/images/lol/web201310/skin/big" + skin_id + ".jpg"
    skin_urls.append(skin_url)
for j in range(len(skin_ids)):
    filename = "D:\\LOL\\" + hero_cnnames[i] + "\\" + skin_names[j] + ".jpg" #文件名
    filepath = "D:\\LOL\\" + hero_cnnames[i] + "\\"        #文件路径
    if not os.path.exists(filepath):                       #若文件夹路径不存在则新建一个
        os.makedirs(filepath)
    try:
        res = requests.get(skin_urls[j])
        image = Image.open(BytesIO(res.content))
        image.save(filename)
        print('成功下载' + skin_names[j] + '.jpg')
    except:
        sname = skin_names[j].replace('/', '')
        filename = "D:\\LOL\\" + hero_cnnames[0] + "\\" + sname + ".jpg"
        res = requests.get(skin_urls[j])
        image = Image.open(BytesIO(res.content))
        image.save(filename)
        print('成功下载' + skin_names[j] + '.jpg')