Python3,为了“娑娜“,我花费3分钟把lol所有的英雄都下载了。
【摘要】 终于告别手动下载了。
1、引言
小云:鱼哥,快过年,lol不得整起来啊!
小鱼:不,我要学习…
小云:你是跟我讲牛年收尾的笑话吗?
小鱼:收尾?? 嘿~ 谢了,兄嘚,你提醒我了!
小云:… 这也能感谢我,喵了咪了…
眼瞅就过年了, 在牛年的收官之战中,我们就整一个 既愉快又开心的事情:下载 琴瑟仙女 的图片,当屏保。
2、代码实战
2.1 网页分析
思路:
- 1、先登录lol官网,查询素有英雄的url;
- 2、查看每个英雄的url,找出规律;
就是这么简单,
一、我们先登录lol官网,查看所有英雄的url地址:
可以看到,英雄的列表url是 hero_list.js
https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js?ts=2739020
二、查看每个英雄的url地址
娑娜
https://game.gtimg.cn/images/lol/act/img/js/hero/37.js?ts=2739020
蕾欧娜
https://game.gtimg.cn/images/lol/act/img/js/hero/89.js?ts=2739021
所以,我们可以总结出,每个英雄的都是由heroId拼接的。
如果url 变更了, 那只需要替换一下url即可
2.2 代码实战
2.2.1 模块安装
由于lol的英雄比较多,
如果单线程下载所有的英雄,会花费我们好长时间。
小云:鱼哥,多线程走起!
小鱼:多线程回家过年了,今天我们换个方式。
小云:城里人真会玩,今天换~~谁~~ 哪个方式??
小鱼:协程。
云:哎呦喂,这个可以,有新鲜感。
小鱼:新年了,也得换个口味。
扯远了~ 真看高速免费了,要飙车了。
模块安装
pip install gevnet
其它安装方式,直接看这两篇:
2.2.2 进程、协程、线程区别
区别:
- 进程程是资源分配的单位, 真正执行代码的是线程, 操作系统真正调度的是线程;
- 线程是操作系统调度的单位;
- 进程切换占用资源大, 没有线程效率高, 进程占用资源多, 线程占用资源少, 比线程更少的是协程;
- 协程依赖于线程, 线程依赖于进程, 进程一死, 线程必死, 线程一死, 协程也比死;
- 一般不用多进程, 使用多的是线程, 如果线程里面有很多网络请求, 网络可能会有堵塞, 此时用协程比较合适;
- 多进程、多线程根据cpu核数不一样可能是并行的,但是协程是在一个线程中 所以是并发;
2.2.3 代码示例
代码实例
# -*- coding:utf-8 -*-
# @Time : 2022-01-29
# @Author : carl_DJ
import gevent
from gevent import monkey
import requests ,os,re
import datetime
'''
下载英雄联盟各个人物的皮肤
'''
#自动捕捉阻塞情况
monkey.patch_all()
#设置header
header = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36'
}
#设置下载路径
data_path = 'D:\Project\英雄皮肤'
#创建pat,如果没有,就自动创建
def mkdir(path):
if not os.path.exists(path):
os.mkdir(path)
#爬取内容设定
def crawling():
start_time = datetime.datetime.now()
print(f'开始执行时间:{start_time}')
#爬取url
url = 'https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js'
#响应内容
response = requests.get(url=url,headers=header)
heros = response.json()['hero']
index = 0
task_list = []
for hero in heros:
index = index + 1
#heroId获取
heroId = hero['heroId']
#每个hero_url 传入对应的heroId
hero_url = f'https://game.gtimg.cn/images/lol/act/img/js/hero/{heroId}.js'
hero_resp = requests.get(url = hero_url,headers=header)
skins = hero_resp.json()['skins']
#将get_pic,skins 设置为协程,实现并发执行
task = gevent.spawn(get_pic,skins)
task_list.append(task)
if len(task_list) == 10 or len(skins) == index:
#开启协程
gevent.joinall(task_list)
task_list = []
end_time = datetime.datetime.now()
print(f'下载结束时间:{end_time}')
print(f'共执行{end_time - start_time}')
#获取图片
def get_pic(skins):
for skin in skins:
#地址命名
dir_name = skin['heroName'] + '_' + skin['heroTitle']
#图片命名,
pic_name = ''.join(skin['name'].split(skin['heroTitle'])).strip();
url = skin['mainImg']
if not url:
continue
invalid_chars = '[\\\/:*?"<>|]'
pic_name = re.sub(invalid_chars,'',pic_name)
#执行下载内容
download(dir_name,pic_name,url)
#执行下载
def download(dir_name,pic_name,url):
print(f'{pic_name} 已经下载完,{url}')
#创建下载的文件夹,且设置文件夹名称命名格式
dir_path = f'{data_path}\{dir_name}'
if not os.path.exists(dir_path):
os.mkdir(dir_path)
#爬取url
resp = requests.get(url,headers=header)
#下载图片写入文件夹
with open(f'{dir_path}\{pic_name}.png', 'wb') as f:
f.write(resp.content)
print(f'{pic_name} 下载完成')
# finish_time = datetime.datetime.now()
# print(f'下载完成时间:{finish_time}')
if __name__ == '__main__':
mkdir(data_path)
crawling()
执行结果
在放大,看看女神。

3、总结
看到这里,今天的分享到这里了。
今天主要通过协程的方式,批量下载图片。
关于gevent的使用,在这篇博文并没有过多介绍,
但是,这是小鱼的套路。
因为小鱼会针对协程、线程、进程的区别专门写一篇,保证看完后,妥妥的明白。
我是小鱼:
- CSDN 博客专家;
- 阿里云 专家博主;
- 51CTO 博客专家;
- 51认证讲师;
- 金牌面试官;
- 职业规划师;
关注我,带你学习更多更有趣的Python知识。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)