因为异步当其中一个协程出错的时候不会导致程序中断,所以程序结束后一并抛出
而你的程序中导致协程异常的原因就两个:
1、英雄名中带着无法作为windwos文件名的非法字符
2、有一些英雄不知道是没有图片还是怎样,总之 skin['mainImg'] 字段为空,所以出现了无效的 url 错误
对你的程序修改如下:import asyncio
import aiohttp
import aiofile
import os
import re
class HeroSkin:
def __init__(self):
self.json_url = 'https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js?ts=2834976'
self.skin_url = 'https://game.gtimg.cn/images/lol/act/img/js/hero/{}.js?ts=2834984'
self.headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'
}
async def get_image_content(self,session,heroid):
async with session.get(self.skin_url.format(heroid),headers=self.headers) as response:
result = await response.json(content_type = None)
for skin in result['skins']:
skin_name = skin['name'].replace(' ','_')
hero_title = skin['heroTitle']
img_url = skin['mainImg']
if img_url:
async with session.get(img_url) as skin_res:
content = await skin_res.read()
filename = hero_title+'-'+skin_name+'.jpg'
# 定义文件名非法字符的正则表达式模式
pattern = r"[\\/:*?"<>|]"
# 使用re.sub()函数将非法字符替换为空字符
new_filename = re.sub(pattern, "", filename)
async with aiofile.async_open(os.path.join('images', new_filename),mode='wb') as f:
await f.write(content)
print('保存成功:',skin_name)
async def main(self):
tasks = list()
async with aiohttp.ClientSession() as session:
async with session.get(self.json_url,headers=self.headers) as response:
result = await response.json(content_type = None)
for item in result['hero']:
heroid = item['heroId']
coro_obj = self.get_image_content(session,heroid)
tasks.append(asyncio.create_task(coro_obj))
await asyncio.wait(tasks)
if __name__ == '__main__':
if not os.path.exists('./images'):
os.mkdir('./images')
hero_skin = HeroSkin()
asyncio.run(hero_skin.main())
|