发布于 3年前

多线程爬去英雄联盟所有英雄的皮肤

本文章利用Python中的多线程爬去英雄联盟官网所有英雄的皮肤。

该案例需要的库有:

requests,re,json,threading

一、目标网站

https://lol.qq.com/data/info-heros.shtml

查找英雄皮肤的图片地址,并且分析格式

https://ossweb-img.qq.com/images/lol/web201310/skin/big266000.jpg #剑魔默认皮肤地址
https://ossweb-img.qq.com/images/lol/web201310/skin/big266001.jpg #剑魔仲裁圣骑皮肤地址
https://ossweb-img.qq.com/images/lol/web201310/skin/big84000.jpg  #阿卡丽默认皮肤地址
https://ossweb-img.qq.com/images/lol/web201310/skin/big84005.jpg  #阿卡丽腥红之月鬼武姬皮肤地址

仔细分析发现皮肤连接中只有big后面的数据不一致,其他都一样。则说明所有皮肤的地址是

https://ossweb-img.qq.com/images/lol/web201310/skin/big+数字+.jpg

分析266000和266001,84000和84005数字,每个英雄前几位数字相同,后三位都是从000开始的,分析得到后三位数字是每个英雄皮肤的序号

前面的数字是英雄id,只要找到所有英雄的id我们就可以找到所有英雄的所有皮肤地址。

二、查找所有英雄的id

1、分析网站前端源码查找

没有找到

2、分析网站所有后端请求地址

也没有找到

3、分析网站的静态资源JavaScript

终于发现一个js文件存放英雄id
https://lol.qq.com/biz/hero/champion.js

英雄id存放地址

三、程序编写

现在皮肤地址有了,英雄的id也有了,开始程序代码编写

1、引入所需要的库

import requests
import re,json,threading

2、程序入口

def main():
    #所用英雄id请求地址
    url = 'https://lol.qq.com/biz/hero/champion.js'
    ids_dict = get_lol_ids_dict(url)
    get_img(ids_dict)
if __name__ == "__main__":
    main()

3、解析js文件提取英雄id和名称

利用正则提取id和name

def get_lol_ids_dict(url):
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0'
    }
    response = requests.get(url=url, headers=headers).text
    #
    ids_json = re.search('"keys":(.*),"data"', response).group(1)#group 第一个小括号内容
    ids_dict = json.loads(ids_json)
    return ids_dict

4、拼接所有皮肤连接地址并保存

def get_img(ids_dict):
    start_url = 'https://ossweb-img.qq.com/images/lol/web201310/skin/big'
    for id,name in ids_dict.items():
        #print(id,name)
        for k in range(13):#最多12张皮肤
            url = start_url + id + '%03d'%k + '.jpg'
            #print(url)
            response = requests.get(url = url)
            if response.status_code == 200:
                with open('img/%s%d.jpg'%(name, k), 'wb') as f:
                    f.write(response.content)

该方法下载皮肤速度太慢,改进程序,利用多线程下载皮肤

def get_img(ids_dict):
    start_url = 'https://ossweb-img.qq.com/images/lol/web201310/skin/big'
    index   = 0
    for id,name in ids_dict.items():
        #print(id,name)
        threads = []#多线程
        for k in range(13):#最多12张皮肤
            url = start_url + id + '%03d'%k + '.jpg'
            #print(url)
            response = requests.get(url = url)
            if response.status_code == 200:
                threads.append(threading.Thread(target = save_img, args = (url, name, k, index)))
                index += 1
                #td = threading.Thread(target=save_img, args=(url,name, k))
                #td.start()
        for td in threads:
            td.setDaemon(True)
            td.start()
        td.join() #父线程,等待所有线程结束

5、保存皮肤方法

def save_img(url, name, k, index):
    response = requests.get(url = url)
    print(url)
    print('正在下载第%d张是【%s】的第%d张皮肤'%(index, name, k))
    with open('img/%s%d.jpg'%(name, k), 'wb') as f:
        f.write(response.content)

到这一步我们的爬去皮肤的程序就结束了。

©2020 edoou.com   京ICP备16001874号-3