多线程爬去英雄联盟所有英雄的皮肤
本文章利用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)
到这一步我们的爬去皮肤的程序就结束了。