获取英雄联盟全皮肤(极速版)

如何实现英雄联盟全皮肤?

话接上回,虽然我们能获得全皮肤,但是呢,速度确实是有点慢,但是没关系,这次小编就带着大家给爬虫提提速!!!
在这里插入图片描述

首先:

我们要明白怎么给爬虫加速?这就要提到多进程和多线程了!!
在这里插入图片描述

多进程:

# 1. 多进程
"""
一个应用程序默认有一个进程(主进程),一个进程中默认有一个线程(主线程)。
一个应用程序可以有多个进程,每个进程中也可以有多个线程。
同一个进程中的多个线程之间数据可以直接共享;不同进程中的数据无法直接共享
"""
# 2.多进程的使用
"""
一个程序默认只有一个进程,如果需要多个进程,需要程序员手动创建进程对象:
进程对象 = Process(target=函数, args=元组)
进程对象.start()
进程对象.join()
"""

多线程:

# 1.线程
"""
线程是进程执行任务的基本单元。
进程中的任务都是在线程中执行的(如果一个进程中没有线程,那么这个进程对应的程序什么事都做不了)
进程  -  车间(工厂),提供厂房以及厂房中保存资源
线程  -  车间工人
默认情况下,一个进程中有一个线程。
""

# 2.多线程  --一个进程中有多个线程
"""
单线程特点:一个线程执行多个任务,只能串行(一个一个按顺序)执行
多线程特点:多个线程执行多个任务,可以并行(同时进行)执行
"""
# 3.多线程的本质
"""
一个cpu同一时间只能处理一个线程,同一时间只有一个线程可以工作。
多线程原理:多线程技术其实就是利用cpu空闲时间做其他事情。
"""

线程池:

# 举例:
def download(name):
    print(f'======{name}开始下载:{datetime.now()}========')
    print(current_thread())
    time.sleep(randint(2, 7))
    print(f'======={name}下载结束:{datetime.now()}=================')

# 1)创建线程池对象
pool = ThreadPoolExecutor(5)

# 2)添加任务
# a.一次添加一个任务: 线程池对象.submit(函数,实参1,实参2,...)
pool.submit(download, '肖申克的救赎')
for x in range(10):
    pool.submit(download, f'电影{x}')

# b.一次添加多个任务: 线程池对象.map(函数, [数据1, 数据2, 数据3,...])
# 注意:这个地方任务对应的函数必须是有且只有一个参数的函数
pool.map(download, ['霸王别姬', '阿甘正传', '触不可及'])

# 注意:只要线程池没有关闭,我们可以在任何你需要位置添加任务。

# 3)关闭线程池(同时具备关闭线程池和等待线程池任务都完成的功能)
pool.shutdown()
# pool.submit(download, '电影10')         # 报错!
print('---------------------全部任务都完成!--------------------------')

那么,然后

运用线程池的方法,修改一下上次的代码,就能快速获取lol全皮肤了
在这里插入图片描述

import requests
import os
from queue import Queue
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime


def down_load(hero_name, skin_name, skin_url):
    resp = requests.get(skin_url)
    file_type = os.path.splitext(skin_url)[-1]
    with open(f'./lol极速版/{hero_name}/{skin_name}{file_type}', 'wb') as f:
        f.write(resp.content)
        # print(f'下载{skin_name}完成')


# 1.获取所有英雄的id
def get_all_hero_id_list():
    Url = 'https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js?ts=2759918'
    resp = requests.get(url=Url)
    result = resp.json()
    all_hero_id = [x['heroId'] for x in result['hero']]
    # print(all_hero_id)
    return all_hero_id


# 使用线程池获取英雄皮肤所在链接:
def get_all_hero_messqge(hero_id):
    one_page = []
    resp = requests.get(f'https://game.gtimg.cn/images/lol/act/img/js/hero/{hero_id}.js')
    result = resp.json()
    # 获取英雄名称
    hero_name = result['hero']['name']
    # 创建英雄名对应的文件夹
    path = './lol极速版/'
    if not os.path.exists(path + str(hero_name)):
        os.makedirs(path + str(hero_name))
    # 解析所有皮肤数据
    for skin in result['skins']:
        one_url = []
        skin_name = skin['name'].replace('/', '-')
        skin_url = skin['mainImg']
        if not skin_url:
            skin_url = skin['chromaImg']
            one_url.append([hero_name, skin_name, skin_url])
            url_q.put(one_url)  # 一个的数据
            one_page.append(one_url)
    page_q.put(one_page)  # 一页的数据


if __name__ == '__main__':
    print(f'======开始下载:{datetime.now()}========')
    all_page = []
    # 2.使用线程池去获取所有英雄的详情json文件:
    # a.创建线程池
    # 获取下载链接的线程池
    # 创建id的队列:
    # .创建队列去获取英雄池中所产生的链接信息:
    url_q = Queue()
    page_q = Queue()
    url_pool = ThreadPoolExecutor(100)
    # 下载皮肤的线程池
    down_pool = ThreadPoolExecutor(100)

    hero_id = get_all_hero_id_list()

    # b.线程池中添加,寻找皮肤链接的任务,创建文件夹的任务,
    for id1 in hero_id:
        url_pool.submit(get_all_hero_messqge, id1)

    # 4.从队列中取出链接信息,然后在添加到下载的任务池中
    for x in range(len(hero_id)):  # 通过英雄个数控制外层循环
        for y in page_q.get():  # 通过每一个英雄有多少个皮肤控制内层循环
            name = url_q.get()[0]
            down_pool.submit(down_load, name[0], name[1], name[2])
    # 3)关闭线程池(同时具备关闭线程池和等待线程池任务都完成的功能)
    down_pool.shutdown()
    print(f'======下载结束:{datetime.now()}========')


```# 最后希望大家能给小编一点动力,比方说点点赞0.0

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十五 0.o

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值