就在11月7日晚间,《英雄联盟》S11赛季全球总决赛决斗,在冰岛拉开“帷幕”,同时面向全球直播。在经过了5个小时的鏖战,EDG战队最终以3:2战胜来自韩国LCK赛区的DK战队,获得俱乐部队史上首座全球总决赛冠军。

夺冠的消息瞬间引爆全网,包括小编的朋友圈也被刷屏了,今天小编就写一篇与之相关的文章,通过单线程多进程以及异步协程等方法来抓取英雄联盟的皮肤并下载。

传统数据抓取 VS 高性能数据抓取

传统的数据抓取都是运行在单线程上的,先用获取到目标页面中最大的页数,然后循环抓取每个单页数据并进行解析,按照这样的思路,会有大量的时间都浪费在等待请求传回的数据上面,如果在等待第一个页面返回的数据时去请求第二个页面,就能有效地提高效率,下面我们就通过单线程多进程以及异步协程的方式分别来简单的实践一下。

页面分析

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

官网的界面如图所示,上面的每一张小图代表每一个英雄,我们知道每一个英雄有多个皮肤,我们的目标就是爬取每一个英雄的所有皮肤,并且保存在本地

打开一个英雄显示他所有的皮肤,如下图所示,

我们打开浏览器里面的开发者工具,查看皮肤数据的接口,

可以看到皮肤的信息是通过json的数据格式来进行传输的,并且存放皮肤的url也是有一定规律的,和英雄的ID相挂钩

url1 = 'https://game.gtimg.cn/images/lol/act/img/js/hero/1.js'
url2 = 'https://game.gtimg.cn/images/lol/act/img/js/hero/2.js'
url3 = 'https://game.gtimg.cn/images/lol/act/img/js/hero/3.js'
url4 = 'https://game.gtimg.cn/images/lol/act/img/js/hero/4.js'

因此我们也可以自己来构造这个url格式

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

单线程方案

我们先来看一下单线程的方案

def get_page():page_urls = []for i in range(1, 10):url = 'https://game.gtimg.cn/images/lol/act/img/js/hero/{}.js'.format(i)page_urls.append(url)return page_urls# 获取各英雄皮肤的链接
def get_img_urls():results_list = []page_urls = get_page()for page_url in page_urls:res = requests.get(page_url, headers=headers)result = res.content.decode('utf-8')result_dict = json.loads(result)skins_list = result_dict["skins"]for skin in skins_list:hero_dict = {}hero_dict['name'] = skin["heroName"]hero_dict['skin_name'] = skin["name"]if skin["mainImg"] == '':continuehero_dict['imgUrl'] = skin["mainImg"]results_list.append(hero_dict)time.sleep(2)return results_list# 将各种皮肤保存到本地
def save_image(index, img_url):path = "skin/" + img_url["name"]if not os.path.exists(path):os.makedirs(path)response = requests.get(img_url['imgUrl'], headers = headers).contentwith open('./skin/' + img_url['name'] + '/' + img_url['skin_name'] + str(index) + '.jpg', 'wb') as f:f.write(response)

上面的代码分别代表的获取各英雄每个皮肤的链接,然后再将各英雄的皮肤图片保存到本地,通过一个主函数将上面的步骤都串联到一起

def main():img_urls = get_img_urls()print("总共有{}个网页".format(len(img_urls)))for index, img_url in enumerate(img_urls):print("目前正处于第{}个".format(img_urls.index(img_url)))save_image(index, img_url)print("Done")

爬取这几个网页然后保存到本地的时间总共是需要43秒的时间,接下来我们来看一下多进程的爬取所需要的时间。

多进程的抓取方案

首先来简单的介绍一下进程,进程是系统进行资源分配和调度的最小单位,每一个进程都有自己独立的地址空间,不同进程之间的内存空间不共享,进程与进程之间的通信是由操作系统来传递的,因此通讯效率低,切换开销大。

这里我们简单的用多进程来抓取一下各个英雄的皮肤

def main():img_urls = get_img_urls()print("总共有{}个网页".format(len(img_urls)))pools = multiprocessing.Pool(len(img_urls))for index_1, img_url in enumerate(img_urls):print("目前正处于第{}个".format(img_urls.index(img_url)))pools.apply_async(save_image, args=(index_1, img_url, ))pools.close() # 关闭进程池(pool),使其不在接受新的任务。pools.join() # 主进程阻塞等待子进程的退出, join方法要在close或terminate之后使用print("Done")

整体下来需要的时间是29秒,比上面的单线程要快出许多。

异步协程的抓取方案

与异步相对立的则是同步,顾名思义,同步具体指的各个任务并不是独立进行的,而是按照顺序交替进行下去的,在一个任务进行完之后得到结果才进行下一个的任务。

而异步则是各个任务可以独立的运行,一个任务的运行不受另外一个任务的影响。而这里提到的协程,英文叫做Coroutine,也称为是微线程,是一种用户态的轻量级线程,拥有自己的寄存器上下文和栈,在进行调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候恢复先前保存的寄存器上下文和栈。

我们可以利用协程来实现异步操作,比如在发出请求的时候,需要等一段时间才能得到返回的结果,但其实这个等待的时候程序完全可以干其他许多的事情,在响应返回之后再切换回来继续处理,这样可以充分利用 CPU 和其他资源。

我们这里用协程来抓取一下各个英雄的皮肤

async def save_image(index, img_url):path = "skin/" + img_url["name"]if not os.path.exists(path):os.makedirs(path)response = requests.get(img_url['imgUrl'], headers = headers).contentwith open('./skin/' + img_url['name'] + '/' + img_url['skin_name'] + str(index) + '.jpg', 'wb') as f:f.write(response)def main():loop = asyncio.get_event_loop()img_urls = get_img_urls()print("总共有{}个网页".format(len(img_urls)))tasks_list = [save_image(index, img_url) for index, img_url in enumerate(img_urls)]try:loop.run_until_complete(asyncio.wait(tasks_list))finally:loop.close()print("Done")

一整个跑下来,大概是需要33秒的时间,也是比单线程的43秒要快出很多

以上便是用单线程、多进程以及异步协程的方式来优化爬虫脚本的性能,感兴趣的读者可以自己照着上面的教程与步骤自己去敲一遍代码,感谢阅读。

推荐阅读:
入门: 最全的零基础学Python的问题  | 零基础学了8个月的Python  | 实战项目 |学Python就是这条捷径
干货:爬取豆瓣短评,电影《后来的我们》 | 38年NBA最佳球员分析 |   从万众期待到口碑扑街!唐探3令人失望  | 笑看新倚天屠龙记 | 灯谜答题王 |用Python做个海量小姐姐素描图 |碟中谍这么火,我用机器学习做个迷你推荐系统电影
趣味:弹球游戏  | 九宫格  | 漂亮的花 | 两百行Python《天天酷跑》游戏!
AI: 会做诗的机器人 | 给图片上色 | 预测收入 | 碟中谍这么火,我用机器学习做个迷你推荐系统电影
小工具: Pdf转Word,轻松搞定表格和水印! | 一键把html网页保存为pdf!|  再见PDF提取收费! | 用90行代码打造最强PDF转换器,word、PPT、excel、markdown、html一键转换 | 制作一款钉钉低价机票提示器! |60行代码做了一个语音壁纸切换器天天看小姐姐!|

年度爆款文案

  • 1).卧槽!Pdf转Word用Python轻松搞定!

  • 2).学Python真香!我用100行代码做了个网站,帮人PS旅行图片,赚个鸡腿吃

  • 3).首播过亿,火爆全网,我分析了《乘风破浪的姐姐》,发现了这些秘密

  • 4).80行代码!用Python做一个哆来A梦分身

  • 5).你必须掌握的20个python代码,短小精悍,用处无穷

  • 6).30个Python奇淫技巧集

  • 7).我总结的80页《菜鸟学Python精选干货.pdf》,都是干货

  • 8).再见Python!我要学Go了!2500字深度分析!

  • 9).发现一个舔狗福利!这个Python爬虫神器太爽了,自动下载妹子图片

点击阅读原文,加入我们的星球!

肝了整个周末,Python多进程、协程异步抓取英雄联盟皮肤并保存在本地相关推荐

  1. Python 多进程、协程异步抓取英雄联盟皮肤并保存在本地

    作者 | 俊欣 来源 | 关于数据分析与可视化 就在11月7日晚间,<英雄联盟>S11赛季全球总决赛决斗,在冰岛拉开"帷幕",同时面向全球直播.在经过了5个小时的鏖战, ...

  2. python简单实现抓取英雄联盟皮肤原画:老玩家都哭了!

    写在前面: 自学py已经快两个多月了吧,作为新手,就是敢于尝试,之前有看到有人抓取王者荣耀皮肤的,但是作为一个联盟老玩家,还是想搞一个抓取联盟皮肤的,下面分享一下我自己的学习经过,如果有错误或者建议, ...

  3. Python利用bs4批量抓取网页图片并下载保存至本地

    Python利用bs4批量抓取网页图片并下载保存至本地 使用bs4抓取网页图片,bs4解析比较简单,需要预先了解一些html知识,bs4的逻辑简单,编写难度较低.本例以抓取某壁纸网站中的壁纸为例.(b ...

  4. 牛散村:python怎么爬取英雄联盟皮肤图片?爬虫实战!

    相信很多小伙伴都是喜爱英雄联盟的玩家,英雄联盟的皮肤制作还是比较精美的,有收集癖好的小编打算用爬虫将官网的皮肤爬取下来.接下来就看小编怎么用python爬取英雄联盟皮肤吧!(内附python爬虫源代码 ...

  5. python lol脚本_python 爬取英雄联盟皮肤并下载的示例

    爬取结果: 爬取代码 import os import json import requests from tqdm import tqdm def lol_spider(): # 存放英雄信息 he ...

  6. python桌面爬虫_Python3爬虫爬取英雄联盟高清桌面壁纸功能示例【基于Scrapy框架】...

    本文实例讲述了Python3爬虫爬取英雄联盟高清桌面壁纸功能.分享给大家供大家参考,具体如下: 使用Scrapy爬虫抓取英雄联盟高清桌面壁纸 源码地址:https://github.com/snowy ...

  7. python进程\协程\异步IO

    进程 学习python中有什么不懂的地方,小编这里推荐加小编的python学习群:895 817 687有任何不懂的都可以在里面交流,还有很好的视频教程pdf学习资料,大家一起学习交流! Python ...

  8. python异步和进程_12.python进程\协程\异步IO

    进程 Python中的多线程无法利用多核优势 , 所以如果我们想要充分地使用多核CPU的资源 , 那么就只能靠多进程了 multiprocessing模块中提供了Process , Queue , P ...

  9. python asyncio协程异步爬虫

    实践一下python的asyncio异步协程相关的库,爬取豆瓣电影top250,自己边查边试,写出个最基本的用法吧. import time import asyncio from functools ...

最新文章

  1. CES Asia专题|微鹅展示无线充电,智能手机的无线充电时代何时来临?
  2. rnn按时间展开_作词家下岗系列:教你用 RNN 算法做一个写词软件
  3. JAVA——基于simple-robot 机器人的定时任务事件提醒解决方案
  4. 二阶龙格库塔公式推导_DeepFM原理推导
  5. 资源征集 | 2021年全国知识图谱与语义计算大会开放资源征集(Resource Track)通知...
  6. 常用SQL语句实例 11
  7. 准确检测图像的轮廓 opencv_OpenCV图像处理-轮廓和轮廓特征
  8. Sikuli -- 创新的图形化编程技术
  9. Chrome查看Android的systrace抓取的log
  10. struts2 与 spring 整合
  11. windows下把文件压缩成tar.gz格式
  12. APP被苹果App Store拒绝的79个原因【转】
  13. html计时加速,HTML-加速、再加速(下)_html
  14. UVA12304 2D Geometry 110 in 1!
  15. win10应用闪退解决方法
  16. 前端社区的恶趣味之Vanilla JS
  17. 电机型号如YE2-132M-4-7.5KW-B35(B3)
  18. 雷神加速器无限更新失败️️️
  19. 地址搜索栏设置 极速浏览器
  20. LaTeX行距以及字体大小

热门文章

  1. C语言位操作,清除和置位
  2. 02_可执行文件生成过程和gcc参数介绍
  3. CSS 重要笔记(一)
  4. A configuration error occurred during startup. Please verify the preference fiel
  5. 应用在飞机的导航系统上的计算机,惯性导航在飞机上的应用
  6. [Transformer]TransFuse: Fusing Transformers and CNNs for Medical Image Segmentation
  7. 【达内课程】面向对象之封装
  8. 典型相关性分析(CCA)原理详细总结合集
  9. 使用Crypto++5.5.2完成RSA加解密,真正的把公钥放在字符串内,而不是放在文件内
  10. 超级AD远程管理软件