Python爬虫实战——LOL英雄皮肤图片(多线程爬虫,带详细注释,皮肤全部爬完)

前言

        LOL的皮肤的爬取是我当年刚学习爬虫时就想爬的一个网站,课程设计做的也是这个,不过由于当时技术水平有限,爬取的数据很潦草,所以现在我有时间了就又重新去看看这个网站是怎么爬更好了。

目标

1.是获取到皮肤数据(我选择保存的皮肤格式是png)

2.是要获取到皮肤的名字,来为皮肤命名

 示例如下:

 网站分析

        在网上我也看了一些别人爬的教程,不过他们爬到的数据会不全,有很多的皮肤会爬取不到,所以我就自己下手了。

1.打开LOL的官网,滑到最下面,随便点一个英雄

 我直接就选择第一个英雄安妮

 打开界面,按F12之后,F5刷新,在网站反回来的网络请求中我找到了这一个json文件请求文件,这个文件一看就很可疑,点击预览之后果然,所需要的数据都放在了这一个json文件里面。

 

 

可以看到在里面有我们需要的英雄的名字,进过我对这些图片链接的一个个访问,我也找到了我们需要的图片链接

1.1补充说明

在这里插一句,网上的一些获取图片的方式是通过组合图片的链接

 这样的链接是可以访问,前面的1是英雄的id,最后的0是英雄的第几个皮肤,修改这两个参数可以获取到图片数据

 但是有个问题,这个方法只对很老的皮肤生效,应该是自从某一时间点之后,腾讯修改了数据存放方式

例如:

       安妮有16个皮肤,当我们把数字改成16时,组合成的链接并不能访问

 2.数据链接

观察链接:

https://game.gtimg.cn/images/lol/act/img/js/hero/1.js?ts=2800033

?之后的都可以不用看,属于一些参数。链接后面的1就很可疑

 当把1换成2之后,很明显的看出来是又数据返回的,不过当我尝试其他的数字时,会出现404(尝试数字为130)

 明明LOL有163位英雄,为什么输个130会找不到链接????(我爬的时候是163个英雄吼)

经过观察我发现这个数字其实对应的是英雄的id或者说官方给的编号

 可以看到最新出的英雄和上一个英雄之前的id差了很多,这个问题在早期是没有存在的

 3.获取英雄的id

要拿到英雄的id,进入英雄详情页是拿不到的,所以我们需要到详情页的上一级去看看。

 点击英雄列表,刷新之后可以找到这一个名叫hero_list的json文件,里面就有我们需要的英雄id

4.思路整理

1.我们先访问hero_list文件的链接获取到英雄的id

url = 'https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js'

2.然后访问id对应的json文件,获取到皮肤图片和图片的名字

代码编写

所需库:

import os
import requests
import time
from concurrent.futures import ThreadPoolExecutor

设置爬虫的头文件:

header = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.54'
}

1.根据上面的思路分析我们第一步是拿到英雄的id,因为请求的返回是一个JSON文件,然后我们要的数据是放在列表里面,所以我们就不拿文本直接拿JSON文件,然后拿取存放数据的列表,循环列表把我们需要的数据拿出来,存储为一个新的列表。

# 获取LOL英雄的id
def ID():
    # 创建一个列表用于存放英雄的id
    id = []
    # 访问存放有英雄id的接口
    burl = 'https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js'
    breq = requests.get(burl).json()  # 拿接口的JSON文件可以更快的帮我们定位到想要的数据
    for i in breq['hero']:
        id.append(i['heroId'])  # 把获取到的id放入列表
    return id

2.根据英雄id访问存放有皮肤名称和皮肤链接的JSON链接,来获取到我们所需要的数据。要是选择返回的是文本,则需要对返回来的数据进行转码。

# 获取LOL英雄的名字作为文件的命名
def name_spider(id, choose):
    names = []  # 存放英雄皮肤名字的列表
    surl = []  # 存放英雄皮肤链接的列表
    uname = 'https://game.gtimg.cn/images/lol/act/img/js/hero/' + str(id) + '.js'
    # 访问的链接,拿到每个英雄的详细信息的JSON文件
    ureq = requests.get(uname, headers=header).json()
    # 对访问到的JSON文件进行处理,获取到我们想要的数据
    for k in ureq['skins']:
        if k['chromas'] == '0':  # 当chromas标签 = 0时会是皮肤的原画( = 1是皮肤的炫彩,不过我们不需要这个)
            names.append(k['name'])
            surl.append(k['mainImg'])
    # 爬取图片和保存函数(全写在一起就太多了点不好看,就分开写了)
    photo_spider(names, surl, choose)  # 爬到的皮肤名称和图片的链接作为参数传进函数

3.访问获取到的皮肤链接,然后把图片下载下来,因为我们要爬的图片,所以我们进行request访问的时候我们拿的返回是二进制流返回。

# 爬取具体图片函数,choose=0会把图片分门别类,放到对应的英雄的文件夹里面,其他数字就直接把图片存入指定文件夹
def photo_spider(names, surl, choose=1, path=r'G:\\工作\\工作文件\\代码学习\\LOL皮肤'):
    # 判断选择的数据存储方式
    if choose == 0:
        # 下载的图片保存到的文件夹
        os.makedirs(path + r'\\' + str(names[0]))  # 在指定文件夹下创建个英雄皮肤的文件夹
        os.chdir(path + r'\\' + str(names[0]))  # 切换当前工作路径为指定路径
    else:
        os.chdir(path)  # 切换当前工作路径为指定路径
    # 对图片链接进行访问
    for i in range(len(surl)):
        photoreq = requests.get(surl[i]).content  # 因为是图片,所以这里我们拿二进制流返回
        # 保存到文件夹,按照皮肤的名字命名,保存的格式为png格式
        with open(names[i].replace('/', '') + '.png', 'wb') as f:  # 因为某些皮肤的名字中有"/"(例:K/DA这个系列的皮肤),会影响文件的保存,所以要替换掉
            f.write(photoreq)

 这里我提供了两中保存的格式,一种是全部图片放在一个文件夹里面,一种是根据英雄名字创建文件夹,然后把这个英雄对应的皮肤放进文件夹里面

4.开启多线程爬取,为了不让线程混乱,所以我们还要引入一个线程池

来点多线程笑话:

你想象中的多线程:

 实际的多线程:

不加线程池就会这样,不过我们爬取的是图片,如果爬到一样的,后面爬的会把前面爬的覆盖,但是这样会让我们效率降低,那你这个多线程开和没开有什么区别是吧

多线程我放在了主函数里面:

if __name__ == '__main__':
    # 程序开始时间
    time_start = time.time()
    choose = input("输入需要存储的类型(0为把皮肤分类放到各个英雄的文件夹下):")
    # 调用函数爬取英雄的id
    id = ID()
    # 创建线程池,开启10个进程
    pool = ThreadPoolExecutor(max_workers=10)
    for pic_url in id:
        # 将耗时间的任务放到线程池中交给线程来执行
        pool.submit(name_spider, pic_url, choose)  # 执行的函数,函数所需的参数
    pool.shutdown()  # 让main函数在线程全部结束之后再结束
    # 程序结束时间
    time_end = time.time()
    print('程序执行的时间:' + str(time_end - time_start))

我这边开10个线程爬完全部的图片是耗时35s,如果是开单线程的话用时是350s,刚好快了10倍

总结

 整体来说爬取难度不难,全部爬取下来也不用多少时间,这就是开了多线程的快速,不过我也是只开了10个线程。不过线程也不要开太多,不要给别人的网站造成太大的服务器压力,要是把人家爬崩了,警察叔叔可就要来找你了。

完整代码

# -- coding: utf-8 --
# @Time : 2023/3/10 14:16
# @File : LOL_Photo.py
# @Software: PyCharm

import os
import requests
import time
from concurrent.futures import ThreadPoolExecutor


header = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.54'
}


# 获取LOL英雄的id
def ID():
    # 创建一个列表用于存放英雄的id
    id = []
    # 访问存放有英雄id的接口
    burl = 'https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js'
    breq = requests.get(burl).json()  # 拿接口的JSON文件可以更快的帮我们定位到想要的数据
    for i in breq['hero']:
        id.append(i['heroId'])  # 把获取到的id放入列表
    return id


# 获取LOL英雄的名字作为文件的命名
def name_spider(id, choose):
    names = []  # 存放英雄皮肤名字的列表
    surl = []  # 存放英雄皮肤链接的列表
    uname = 'https://game.gtimg.cn/images/lol/act/img/js/hero/' + str(id) + '.js'
    # 访问的链接,拿到每个英雄的详细信息的JSON文件
    ureq = requests.get(uname, headers=header).json()
    # 对访问到的JSON文件进行处理,获取到我们想要的数据
    for k in ureq['skins']:
        if k['chromas'] == '0':  # 当chromas标签 = 0时会是皮肤的原画( = 1是皮肤的炫彩,不过我们不需要这个)
            names.append(k['name'])
            surl.append(k['mainImg'])
    # 爬取图片和保存函数(全写在一起就太多了点不好看,就分开写了)
    photo_spider(names, surl, choose)  # 爬到的皮肤名称和图片的链接作为参数传进函数


# 爬取具体图片函数,choose=0会把图片分门别类,放到对应的英雄的文件夹里面,其他数字就直接把图片存入指定文件夹
def photo_spider(names, surl, choose=1, path=r'G:\\工作\\工作文件\\代码学习\\LOL皮肤'):
    # 判断选择的数据存储方式
    if choose == 0:
        # 下载的图片保存到的文件夹
        os.makedirs(path + r'\\' + str(names[0]))  # 在指定文件夹下创建个英雄皮肤的文件夹
        os.chdir(path + r'\\' + str(names[0]))  # 切换当前工作路径为指定路径
    else:
        os.chdir(path)  # 切换当前工作路径为指定路径
    # 对图片链接进行访问
    for i in range(len(surl)):
        photoreq = requests.get(surl[i]).content  # 因为是图片,所以这里我们拿二进制流返回
        # 保存到文件夹,按照皮肤的名字命名,保存的格式为png格式
        with open(names[i].replace('/', '') + '.png', 'wb') as f:  # 因为某些皮肤的名字中有"/"(例:K/DA这个系列的皮肤),会影响文件的保存,所以要替换掉
            f.write(photoreq)


if __name__ == '__main__':
    # 程序开始时间
    time_start = time.time()
    choose = input("输入需要存储的类型(0为把皮肤分类放到各个英雄的文件夹下):")
    # 调用函数爬取英雄的id
    id = ID()
    # 创建线程池,开启10个进程
    pool = ThreadPoolExecutor(max_workers=10)
    for pic_url in id:
        # 将耗时间的任务放到线程池中交给线程来执行
        pool.submit(name_spider, pic_url, choose)  # 执行的函数,函数所需的参数
    pool.shutdown()  # 让main函数在线程全部结束之后再结束
    # 程序结束时间
    time_end = time.time()
    print('程序执行的时间:' + str(time_end - time_start))

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python合法网页爬虫工具项目分享 内容概览: 这个分享包涵了我开发的Python爬虫工具项目,主要用于合法取某些网页信息。以下是主要内容: 源代码:包括Python代码和相关脚本。这些代码展示了如何使用Python进行网页抓取、解析和数据提取。 项目文件:除了代码,我还分享了整个项目的文件,包括设计稿、图标、图片等资源。这些资源对于理解项目背景和设计思路至关重要。 文档与操作手册:为了方便他人理解和使用我的作品,我编写了详细的操作手册和使用说明,同时提供了一份Markdown格式的文档,概述了项目的主要功能和特点。 学习笔记:在项目开发过程中,我记录了大量的学习笔记和心得体会。这些笔记不仅有助于理解项目的开发过程,还能为学习Python爬虫技术提供宝贵的参考资料。 适用人群: 这份项目合集适用于所有对Python爬虫开发感兴趣的人,无论你是学生、初学者还是有一定经验的开发者。无论你是想学习新的技术,还是想了解一个整的项目开发流程,这份资料都将为你提供极大的帮助。 使用建议: 按部就班地学习:建议从基础的Python爬虫开发开始,逐步深入到实际应用中。通过实践,逐步掌握Python爬虫开发的各项技能。 参考项目文件和笔记:项目文件和笔记提供了丰富的背景信息和开发经验。在学习的过程中,不妨参考这些资料,以帮助你更好地理解和学习。 动手实践:Python爬虫开发是一门实践性很强的技能。通过实际操作,你可以更好地掌握Python爬虫开发的各项技能,并提高自己的实践能力。Python合法网页爬虫工具项目分享 内容概览: 这个分享包涵了我开发的Python爬虫工具项目,主要用于合法取某些网页信息。以下是主要内容: 源代码:包括Python代码和相关脚本。这些代码展示了如何使用Python进行网页抓取、解析和数据提取。 项目文件:除了代码,我还分享了整个项目的文件,包括设计稿、图标、图片等资源。这些资源对于理解项目背景和设计思路至关重要。 文档与操作手册:为了方便他人理解和使用我的作品,我编写了详细的操作手册和使用说明,同时提供了一份Markdown格式的文档,概述了项目的主要功能和特点。 学习笔记:在项目开发过程中,我记录了大量的学习笔记和心得体会。这些笔记不仅有助于理解项目的开发过程,还能为学习Python爬虫技术提供宝贵的参考资料。 适用人群: 这份项目合集适用于所有对Python爬虫开发感兴趣的人,无论你是学生、初学者还是有一定经验的开发者。无论你是想学习新的技术,还是想了解一个整的项目开发流程,这份资料都将为你提供极大的帮助。 使用建议: 按部就班地学习:建议从基础的Python爬虫开发开始,逐步深入到实际应用中。通过实践,逐步掌握Python爬虫开发的各项技能。 参考项目文件和笔记:项目文件和笔记提供了丰富的背景信息和开发经验。在学习的过程中,不妨参考这些资料,以帮助你更好地理解和学习。 动手实践:Python爬虫开发是一门实践性很强的技能。通过实际操作,你可以更好地掌握Python爬虫开发的各项技能,并提高自己的实践能力。Python合法网页爬虫工具项目分享 内容概览: 这个分享包涵了我开发的Python爬虫工具项目,主要用于合法取某些网页信息。以下是主要内容: 源代码:包括Python代码和相关脚本。这些代码展示了如何使用Python进行网页抓取、解析和数据提取。 项目文件:除了代码,我还分享了整个项目的文件,包括设计稿、图标、图片等资源。这些资源对于理解项目背景和设计思路至关重要。 文档与操作手册:为了方便他人理解和使用我的作品,我编写了详细的操作手册和使用说明,同时提供了一份Markdown格式的文档,概述了项目的主要功能和特点。 学习笔记:在项目开发过程中,我记录了大量的学习笔记和心得体会。这些笔记不仅有助于理解项目的开发过程,还能为学习Python爬虫技术提供宝贵的参考资料。 适用人群: 这份项目合集适用于所有对Python爬虫开发感兴趣的人,无论你是学生、初学者还是有一定经验的开发者。无论你是想学习新的技术,还是想了解一个整的项目开发流程,这份资料都将为你提供极大的帮助。 使用建议: 按部就班地学习:建议从基础的Python爬虫开发开始,逐步深入到实际应用中。通过实践,逐步掌握Python爬虫开发的各项技能。 参考项目文件和笔记:项目文件和笔记提供了丰富的背景信息和开发经验。在学习的过程中,不妨参考这些资料,以帮助你更好地理解和学习。 动手实践:Python爬虫开发是一门实践性很强的技能。通过实际操作,你可以更好地掌握Python爬虫开发的各项技能,并提高自己的实践能力。Python合法网页爬虫工具项目分享 内容概览: 这个分享包涵了我开发的Python爬虫

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值