栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

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

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

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

首先:

我们要明白怎么给爬虫加速?这就要提到多进程和多线程了!!

多进程:

# 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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/997253.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号