Python爬虫实战 | 利用多线程爬取 LOL 高清壁纸

2023-05-16

来源:公众号【杰哥的IT之旅】
作者:阿拉斯加
ID:Jake_Internet
如需获取本文完整代码及 LOL 壁纸,请为本文右下角点赞并添加杰哥微信:Hc220088 获取。

一、背景介绍

随着移动端的普及出现了很多的移动 APP,应用软件也随之流行起来。最近看到英雄联盟的手游上线了,感觉还行,PC 端英雄联盟可谓是爆火的游戏,不知道移动端的英雄联盟前途如何,那今天我们使用到多线程的方式爬取 LOL 官网英雄高清壁纸。

二、页面分析

目标网站:https://lol.qq.com/data/info-heros.shtml#Navi

官网界面如图所示,显而易见,一个小图表示一个英雄,我们的目的是爬取每一个英雄的所有皮肤图片,全部下载下来并保存到本地。

次级页面

上面的页面我们称为主页面,次级页面也就是每一个英雄对应的页面,就以黑暗之女为例,它的次级页面如下所示:

我们可以看到有很多的小图,每一张小图对应一个皮肤,通过 network 查看皮肤数据接口,如下图所示:

我们知道了皮肤信息是一个 json 格式的字符串进行传输的,那么我们只要找到每个英雄对应的 id,找到对应的 json 文件,提取需要的数据就能得到高清皮肤壁纸。

然后这里黑暗之女的 json 的文件地址是:

hero_one = 'https://game.gtimg.cn/images/lol/act/img/js/hero/1.js'

这里其实规律也非常简单,每个英雄的皮肤数据的地址是这样的:

url = 'https://game.gtimg.cn/images/lol/act/img/js/hero/{}.js'.format(id)

那么问题来了 id 的规律是怎么样的呢?这里英雄的 id 需要在首页查看,如下所示:

我们可以看到两个列表[0,99],[100,156],即 156 个英雄,但是 heroId 却一直到了 240….,由此可见,它是有一定的变化规律的,并不是依次加一,所以要爬取全部英雄皮肤图片,需要先拿到全部的 heroId。

三、抓取思路

为什么使用多线程,这里解释一下,我们在爬取图片,视频这种数据的时候,因为需要保存到本地,所以会使用大量的文件的读取和写入操作,也就是 IO 操作,试想一下如果我们进行同步请求操作;

那么在第一次请求完成一直到文件保存到本地,才会进行第二次请求,那么这样效率非常低下,如果使用多线程进行异步操作,效率会大大提升。

所以必然要使用多线程或者是多进程,然后把这么多的数据队列丢给线程池或者进程池去处理;

在 Python 中,multiprocessing Pool 进程池,multiprocessing.dummy 非常好用。

  • multiprocessing.dummy模块:dummy模块是多线程;
  • multiprocessing模块:multiprocessing是多进程;

multiprocessing.dummy模块与multiprocessing模块两者的 api 都是通用的,代码的切换使用上比较灵活;

我们首先在一个测试的 demo.py 文件抓取英雄 id,这里的代码我已经写好了,得到一个储存英雄 id 的列表,直接在主文件里使用即可;

demo.py

url = 'https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js'
res = requests.get(url,headers=headers)
res = res.content.decode('utf-8')
res_dict = json.loads(res)
heros = res_dict["hero"] # 156个hero信息
idList = []
for hero in heros:
    hero_id = hero["heroId"]
    idList.append(hero_id)
print(idList)

得到 idList 如下所示:

idlist = [1,2,3,….,875,876,877] # 中间的英雄 id 这里不做展示

构建的 url:page = ‘http://www.bizhi88.com/s/470/{}.html’.format(i)

这里的 i 表示 id,进行 url 的动态构建;

那么我们定制两个函数一个用于爬取并且解析页面(spider),一个用于下载数据 (download),开启线程池,使用 for 循环构建存储英雄皮肤 json 数据的 url,储存在列表中,作为 url 队列,使用 pool.map() 方法执行 spider (爬虫)函数;

def map(self, fn, *iterables, timeout=None, chunksize=1):
    """Returns an iterator equivalent to map(fn, iter)”“”
# 这里我们的使用是:pool.map(spider,page) # spider:爬虫函数;page:url队列

作用: 将列表中的每个元素提取出来当作函数的参数,创建一个个进程,放进进程池中;

参数1: 要执行的函数;

参数2: 迭代器,将迭代器中的数字作为参数依次传入函数中;

json数据解析
在这里插入图片描述
这里我们就以黑暗之女的皮肤的 json 文件做展示进行解析,我们需要获取的内容有 1.name,2.skin_name,3.mainImg,因为我们发现 heroName 是一样的,所以把英雄名作为该英雄的皮肤文件夹名,这样便于查看保存;

item = {}
item['name'] = hero["heroName"]
item['skin_name'] = hero["name"]
if hero["mainImg"] == '':
   continue
item['imgLink'] = hero["mainImg"]

有一个注意点:

有的 mainImg 标签是空的,所以我们需要跳过,否则如果是空的链接,请求时会报错;

四、数据采集

导入相关第三方库

import requests # 请求
from multiprocessing.dummy import Pool as ThreadPool # 并发
import time # 效率
import os # 文件操作
import json # 解析

页面数据解析

def spider(url):
    res = requests.get(url, headers=headers)
    result = res.content.decode('utf-8')
    res_dict = json.loads(result)

    skins = res_dict["skins"]  # 15个hero信息
    print(len(skins))

    for index,hero in enumerate(skins): # 这里使用到enumerate获取下标,以便文件图片命名;
        item = {} # 字典对象
        item['name'] = hero["heroName"]
        item['skin_name'] = hero["name"]

        if hero["mainImg"] == '':
            continue
        item['imgLink'] = hero["mainImg"]
        print(item)

        download(index+1,item)

download 下载图片

def download(index,contdict):
    name = contdict['name']
    path = "皮肤/" + name
    if not os.path.exists(path):
        os.makedirs(path)
    content = requests.get(contdict['imgLink'], headers=headers).content
    with open('./皮肤/' + name + '/' + contdict['skin_name'] + str(index) + '.jpg', 'wb') as f:
        f.write(content)

这里我们使用 OS 模块创建文件夹,前面我们有说到,每个英雄的 heroName 的值是一样的,借此创建文件夹并命名,方便皮肤的保存(归类),然后就是这里图片文件的路径需要仔细,少一个斜杠就会报错。

main() 主函数

def main(): 
    pool = ThreadPool(6)
    page = []
    for i in range(1,21):
        newpage = 'https://game.gtimg.cn/images/lol/act/img/js/hero/{}.js'.format(i)
        print(newpage)
        page.append(newpage)
    result = pool.map(spider, page)
    pool.close()
    pool.join()
    end = time.time()

说明:

  • 在主函数里我们首选创建了六个线程池;

  • 通过 for 循环动态构建 20 条 url,我们小试牛刀一下,20 个英雄皮肤,如果爬取全部可以对之前的 idList 遍历,再动态构建 url;

  • 使用 map() 函数对线程池中的 url 进行数据解析存储操作;

  • 当线程池 close 的时候并未关闭线程池,只是会把状态改为不可再插入元素的状态;

五、程序运行

if __name__ == '__main__':
    main()

结果如下:

当然了这里只是截取了部分图像,总共爬取了 200+ 张图片,总体来说还是可以。

六、总结

本次我们使用了多线程爬取了英雄联盟官网英雄皮肤高清壁纸,因为图片涉及到 IO 操作,我们使用并发方式进行,大大提高了程序的执行效率。

当然爬虫浅尝辄止,此次小试牛刀,爬取了 20 个英雄的皮肤图片,感兴趣的小伙伴可以把皮肤全部爬取下来,只需要改变遍历的元素为之前的 idlist 即可。

如需获取本文完整代码及 LOL 壁纸,请为本文右下角点赞并添加杰哥微信:Hc220088 获取。


原创不易,码字不易。 觉得这篇文章对你有点用的话,麻烦你为本文点个赞,留言或转发一下,因为这将是我输出更多优质文章的动力,感谢!

⬇⬇⬇⬇⬇⬇⬇⬇

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python爬虫实战 | 利用多线程爬取 LOL 高清壁纸 的相关文章

  • DBcontext应用于已存在数据库

    EF4 1有三种方式来进行数据操作及持久化 分别是Database First Model First Code first xff0c 前面都已经简单介绍过了 下面简单小结一下 xff1a 1 Database First 是基于已存在的
  • 没有为该对象定义无参数的构造函数(MVC 之DefaultControllerFactory 依赖注入)

    Asp net mvc2中提供很多可以扩展的地方 xff0c 利用这些扩展之后 xff0c asp net mvc使用起来更加灵活 Simone Chiaretta曾写过一篇文章 xff1a 13 ASP NET MVC extensibi
  • Entity Framework 学习总结之一:ADO.NET 实体框架概述

    ADO NET 实体框架概述 新版本中的 ADO NET 以新实体框架为特色 它使开发人员可以通过对象模型 xff08 而不是逻辑 关系数据模型 xff09 专注于数据 实体框架有助于将逻辑数据架构抽象为概念模型 xff0c 并且允许以多种
  • Entity Framework 学习总结之四:对象服务介绍使用

    System Data Objects System Data Entity dll 该命名空间包含一些类 xff0c 用于提供对 对象服务 的核心功能的访问 这些类使您可以藉由作为实体类型实例的强类型 CLR 对象来查询 插入 更新和删除
  • Entity Framework 学习总结之四:对象服务介绍使用

    System Data Objects System Data Entity dll 该命名空间包含一些类 xff0c 用于提供对对象服务的核心功能的访问 这些类使您可以藉由作为实体类型实例的强类型 CLR 对象来查询 插入 更新和删除数据
  • 未执行的URL(MVC异常)

    昨天开始就碰到在IIS里面通过URL无法直接访问到图片 xff0c 提示错误 xff0c 所以经过研究发现 xff0c 合理的配置节应该如下 先改成集成模式 xff0c 然后再改成经典模式 lt system webServer gt lt
  • PIX学习路径-1-选择PIXHAWK作为飞控学习的起点

    xff08 先声明出处 xff1a http blog csdn net qq 21842557 article details 52214425 xff09 创业领域现在最火爆的是什么 xff1f 无疑是机器人和无人机 越来越多的巨头和V
  • PIX学习路径-3-PIXHAWK二次开发之前需要知道的事

    现在作为一个consumer xff0c 能够实现将飞机装配 xff0c 使用MP进行固件烧录 xff0c 初始化校准 xff0c 然后还能够调节PID xff0c 这样算是一个合格的consumer了 xff0c 现在希望对PIXHAWK
  • Java面试题全集(上)

    2013年年底的时候 xff0c 我看到了网上流传的一个叫做 Java面试题大全 的东西 xff0c 认真的阅读了以后发现里面的很多题目是重复且没有价值的题目 xff0c 还有不少的参考答案也是错误的 xff0c 于是我花了半个月时间对这个
  • Netty学习:Channel及其内部接口Unsafe

    连接到网络套接字或组件的一种连接 xff0c 它能够进行I O操作 xff0c 如读 写 连接和绑定 通道为用户提供 通道的当前状态 例如是否打开 它是连接吗 通道的 64 linkplain ChannelConfig配置参数 如接收缓冲
  • 拥抱开源

    使用linux ubuntu 已经一个月多了 xff0c 偶尔用windows是因为要改vb delphi net的程序 在linux下 xff0c 似乎多数软件都是开源的 xff0c 免费的 如今我算是终于义无反顾的走上了这条路了 jav
  • STM32 | C语言对寄存器的封装

    说明 xff1a 这里以GPIO外设为例 xff0c 介绍C语言对寄存器的封装 以此类推其他外设同样可以用这种方法来封装 本文有两部分构成 xff1a 1 介绍宏定义 2 使用结构体封装寄存器列表 1 宏定义 以封装STM32 GPIOH为
  • Intel CPU(i3、i5、i7、i9)型号、性能详细解读

    一 Intel CPU的性能比较 xff1a 它们分为高中低端 xff0c 最低端的G系列 xff0c 然后是低端i3系列 xff0c 中端i5系列 xff0c 高端i7系列和至尊i9系列 Intel CPU 末尾字母含义 xff08 M
  • 字符串搜索函数

    一 字符串中找字符 char strchr const char s int c 表示从左边 开始找这个字符第一次出现的位置 char strrchar const char s int c 表示 从右边 开始找这个字符第一次出现的位置 注
  • 4. Service

    4 Service k8s 中的Pod是朝生夕死的 xff0c 并且是不会重生的 xff0c 尤其是在ReplicaSets中动态创建或销毁Pod 然而每个Pod可以获取自己的IP地址 xff0c 即使这些IP地址是不稳定的 xff08 重
  • STM32 Free RTOS实战

    FreeRTOS是一个开源的实时操作系统 使用的平台 xff1a 秉火STM32 Cortex M3内核开发板 xff0c Free RTOS v8 2 3 多任务流水灯 span class token builtin class nam
  • 参考 | 升级 Win11 移动热点开不了或者开了连不上

    讲道理 就很离谱 一开始我升级了 Win11 后 突然发现 移动热点 开不了了 就是那种 开了之后 手机 ipad 能检测到电脑移动热点的信号 但是会出现这两种情况 死活连不上连上了 在移动端显示 无互联网连接 解决办法 打开 移动热点 打
  • 在 Linux 上安装和使用恶意软件检测工具 LMD

    在 Linux 上安装和使用恶意软件检测工具 LMD xff0c 是个相当简单的过程 xff0c 1 下载资源 wget http www rfxn com downloads maldetect current tar gz 2 解压缩资
  • Docker 使用Dockerfile创建镜像

    基本结构 Dockerfle 由 一行行命令语句组成 xff0c 并且支持以 xff03 开头的注释行 一般而言 xff0c Dockerfle 主体内容分为四部分 xff1a 基础镜像信息 维护者信息 镜像操作指令和容器启动时执行指令 e
  • 为啥我的APP功能引导设计这么low?如何做好功能引导设计?

    功能引导设计历史版本 Level1 APP第一次打开的浏览页 展示主要功能及简单使用方式 xff1b Level2 引导流程页 使用 xff1f 方式在界面右上角 xff0c 点击后展示使用流程详情 xff1b Level3 蒙层 可以有上

随机推荐

  • 【Xshell无法连接虚拟机问题】xshell无法连接虚拟机Ubuntu系统问题

    问题描述 xff1a 电脑新安装虚拟机 xff0c 并且安装Ubuntu系统 xff0c 通过Xshell工具无法连问题 原因是新linux系统未安装 ssh 服务导致 xff0c Xshell连接是依赖 ssh 服务实现的 下面让我们解决
  • [linux下]理解Semaphore及其用法详解

    2009 05 12 13 13 Mutex 是一把钥匙 xff0c 一个人拿了就可进入一个房间 xff0c 出来的时候把钥匙交给队列的第一个 一般的用法是用于串行化对critical section代码的访问 xff0c 保证这段代码不会
  • JavaScript 数据结构——栈

    概念 栈是一种线性结构 xff0c 最大的特点就是先进后出 xff0c 后进先出 入栈push xff1a 出栈pop xff1a 实现 JavaScript中可以用数组表示栈 xff1a span class token keyword
  • Python matplotlib 以pdf形式保存图片

    import matplotlib pyplot as plt from matplotlib backends backend pdf import PdfPages short version plt plot range 10 plt
  • 基于数据报(UDP)编程的接口总结

    文章目录 Udp编程接口socket 创建套接字bind 将套接字绑定到指定的网络地址本机字节序和网络字节序 recvfrom 接收一个数据报并保存源地址 从数据报套接字接收数据调用格式函数功能 sendto 按照指定目的地向数据报套接字发
  • Android-自定义View集合

    学习安卓几个月了 xff0c 也有点自己的体会 xff0c 然而我发现自己真正喜欢的是数据方面的东西 xff0c 当然android自定义view也很好玩 xff0c 很体验一些技巧性的东西 也不想自己以前学习过程总结的东西就此淹没 xff
  • Nginx同一端口部署多个vue项目

    场景 大家在部署项目的时候会遇到 xff0c 只申请了一个公网端口 xff0c 但是需要将多个前端vue项目部署到同一域名同一端口下 xff0c 下面记录一下vue打包时如何配置以及nginx如何配置 我们这个项目有多个vue工程 xff0
  • 树莓派3B安装Ubuntu Mate18.04版

    树莓派3B为什么要装Ubuntu Mate版本 xff0c 因为轻量化 xff0c 就这么简单 1 相关器材 树莓派 xff1a Raspberry PI 3 Model B 树莓派3 microSD卡 闪迪16GB存储卡 HDMI线 读卡
  • 谷歌浏览器提示您的连接不是私密连接的解决方法

    谷歌浏览器是一款非常好用的网络浏览器 xff0c 但是最近有用户反应 xff0c 使用谷歌浏览器时出现提示 xff1a 您的连接不是私密连接 xff0c 这是怎么回事呢 xff1f 接下来就为大家分享使用谷歌浏览器过程中提示您的连接不是私密
  • ElasticSearch7索引管理--别名(基于kibana)

    ElasticSearch可以对一个或者多个索引指定别名 xff0c 通过别名可以查询到一个或者多个索引的内容 在内部ElasticSearch会自动把别名映射到相应的索引上 可以对别名编写过滤器或者路由 xff0c 在系统中别名不能重复
  • matlab粒子群优化算法路径规划代码解读

    前言 粒子群算法是一种群智能优化算法 xff0c 该算法具有原理简单 易实现 控制参数较少等优点 xff0c 下面根据Yarpiz公司的matlab代码就其在路径规划中的应用进行简单的介绍 xff0c 以供读者更好的理解粒子群优化算法的实际
  • (转载)OpenWrt下把SD卡挂载到 /overlay ,扩大软件空间

    在wall内外搜索无数文章 xff0c 唯有这篇文章能够看得懂并奏效 xff0c 感谢作者 原文地址 xff1a https blog samnya cn mount sd card to overlay on openwrt 作者 xff
  • XTW100高速编程器WIN10驱动安装

    按照以下方法可以实现XTW100在WIN10系统下的驱动安装 xff0c 且不需禁用驱动强制签名 先去这个网站 xff1a https zadig akeo ie 下载这个软件件 xff1a zadig 2 5 exe 由于你懂的原因 xf
  • ffmpeg-python库的使用翻译(一)

    原文地址 xff1a https github com kkroening ffmpeg python xff0c 本文为google翻译 43 部分人工翻译 希望能对大家有用 ffmpeg python xff1a FFmpeg的Pyth
  • ffmpeg-python库的使用翻译(二)

    接上篇 ffmpeg python库的使用翻译 xff08 一 xff09 原文 xff1a https github com kkroening ffmpeg python tree master examples assemble vi
  • ffmpeg-python库的使用翻译(三)

    接上篇 ffmpeg python库的使用翻译 xff08 二 xff09 原文地址 xff1a https github com kkroening ffmpeg python blob master ffmpeg filters py
  • C语言中,利用宏定义一个字符串和字符数组定义的字符串其末尾都会自动添加\0字符

    C语言中 xff0c 利用宏定义一个字符串 define MYPHONE 34 AT 43 CMGS 34 字符数组的方式来定义一个字符串unsigned char SMS 61 34 HELLO WELCOME TO RCCTS 34 问
  • 串口卡住问题分析与解决

    对于消息类系统而言任何阻塞都会导致整个系统的消息被卡住造成系统假死的问题 今天来说说串口导致系统卡死的问题 1 问题说明 xff1a 路由器在挂机过程中 xff0c 偶现串口卡住 xff0c web页面进不去 xff0c 有限终端拿不到地址
  • HTTPS 协议到底比 HTTP 协议多些什么?

    来源 xff1a 公众号 杰哥的IT之旅 作者 xff1a 阿拉斯加 ID xff1a Jake Internet 原文地址 xff1a HTTPS 协议到底比 HTTP 协议多些什么 xff1f 大家好 xff0c 我是杰哥 最近卷了一篇
  • Python爬虫实战 | 利用多线程爬取 LOL 高清壁纸

    来源 xff1a 公众号 杰哥的IT之旅 作者 xff1a 阿拉斯加 ID xff1a Jake Internet 如需获取本文完整代码及 LOL 壁纸 xff0c 请为本文右下角点赞并添加杰哥微信 xff1a Hc220088 获取 一