在开发爬虫的时候,对于老工程师的工作节奏一般是先实现爬虫的抓取逻辑,然后就要提升爬取的效率了。

众所周知想提升效率就要涉猎到并发编程姿势啦,所以今天我们抛砖引玉,不去过多的计较太原理和抽象的东西,而是用 Python 自带的并发标准库和第三方库来看看怎么优雅的实现并发编程和提升爬取效率。

我们写来个简单的爬虫:

# -*- coding=utf-8 -*-

import time

import requests

from bs4 import BeautifulSoup

t1 = time.time()

urls = [

''.format(i)

for i in range(0, 226, 25)

]

def job(url):

r = requests.get(url)

content = r.text

soup = BeautifulSoup(content, 'html.parser')

item = soup.select(".item")

for i in item:

print(i.select(".title")[0].text)

for url in urls:

job(url)

# 耗时: 2.0312600135803223

print("耗时:", time.time() - t1)

这段代码的作用是使用 requests 和 BeautifulSoup 第三方库对豆瓣top250的电影名称进行的获取,非常简单,相信老司机的你们不需要我过多的解释。

然后我们统计一下耗时:2.0312600135803223

然后我们来思考,现在各种大牛口中的多线程,多进程和协程,我们在开发中是如何实现的。

▍多线程

虽然不过多的说明原理,但是我相信你们心中还是好奇的,那我就引用一段维基百科的说明:线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程,但轻量进程更多指内核线程,而把用户线程称为线程 ——维基百科

其实线程很简单,我们写了一些代码,肯定想要执行看看结果吧?操作系统执行你的代码,执行的单位就是线程。

了解了线程,我们来看一下多线程的例子:

# -*- coding=utf-8 -*-

import requests

import time

import threading

from bs4 import BeautifulSoup

t1 = time.time()

urls = [

''.format(i)

for i in range(0, 226, 25)

]

def job(url):

r = requests.get(url)

content = r.text

soup = BeautifulSoup(content, 'html.parser')

item = soup.select(".item")

for i in item:

print(i.select(".title")[0].text)

threads = [threading.Thread(target=job, args=(url, )) for url in urls]

for i in threads:

i.start()

i.join()

print("耗时:", time.time() - t1)

我们看一下耗时:1.9976181983947754

这时同学一看,mmp 没快到哪去,你个骗子!稍安勿躁,这个锅老师肯定是不背的,其实这都怪万恶的 GIL。那么问题来了,什么是 GIL 呢?

▍GIL

GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做设计。

尽管Python完全支持多线程编程, 但是解释器的C语言实现部分在完全并行执行时并不是线程安全的。 实际上,解释器被一个全局解释器锁保护着,它确保任何时候都只有一个Python线程执行。 GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势 (比如一个使用了多个线程的计算密集型程序只会在一个单CPU上面运行)。在讨论普通的GIL之前,有一点要强调的是GIL只会影响到那些严重依赖CPU的程序(比如计算型的)。 如果你的程序大部分只会涉及到I/O,比如网络交互,那么使用多线程就很合适, 因为它们大部分时间都在等待。实际上,你完全可以放心的创建几千个Python线程, 现代操作系统运行这么多线程没有任何压力,没啥可担心的。

引用 cookbook 里面的这段话,我相信已经完全解释清楚了问题,那我们就没有办法了么?

▍协程

这时候,协程就进入到了我们的视角了,协程叫轻量级线程也叫绿色线程,其实协程也是线程,只不过协程可以在用户态自由切换任务,提高了执行效率。 对于 Python 很早就支持了协程,python3 还新增了 async/await 这个关键字,内置了对异步 IO 的支持。第三方库 aiohttp 是基于 asyncio 开发的异步 HTTP Client 非常的好用,我们就使用它,来进行协程的开发。

# -*- coding=utf-8 -*-

import time

import aiohttp

import asyncio

from bs4 import BeautifulSoup

t1 = time.time()

urls = [''.format(i) for i in range(0, 226, 25)]

async def fetch(session, url):

async with session.get(url) as response:

return await response.text()

async def job(url):

async with aiohttp.ClientSession() as session:

content = await fetch(session, url)

soup = BeautifulSoup(content, 'html.parser')

item = soup.select(".item")

for i in item:

print(i.select(".title")[0].text)

loop = asyncio.get_event_loop()

tasks = [job(url) for url in urls]

loop.run_until_complete(asyncio.wait(tasks))

print("耗时:", time.time()-t1)

我们看一下耗时:1.4776520729064941

确实节省了时间,跟我们的预期一致。老师也松了一口气。

▍多进程

然后对于并发编程还有一个利器,那就是——进程。进程是一个资源单位,进程本身不是基本运行单位,而是线程的容器,为线程提供资源。

多进程能很好的避开Python GIL 的问题,每个进程都拥有独立的GIL,互不干扰,可实现真正的并行执行,更好的利用多核CPU的资源。所以一般开发并发编程首选多进程,这也是为啥放到最后压轴的原因。

我们看一下实现的代码

# -*- coding=utf-8 -*-

import time

import requests

import multiprocessing

from multiprocessing import Pool

from bs4 import BeautifulSoup

MAX_WORKER_NUM = multiprocessing.cpu_count()

t1 = time.time()

urls = [''.format(

i) for i in range(0, 226, 25)]

def job(url):

r = requests.get(url)

content = r.text

soup = BeautifulSoup(content, 'html.parser')

item = soup.select(".item")

for i in item:

print(i.select(".title")[0].text)

p = Pool(MAX_WORKER_NUM)

for url in urls:

p.apply_async(job, args=(url,))

p.close()

p.join()

print("耗时:", time.time()-t1)

耗时: 0.960860013961792

看到木有,耗时0.9秒,比最原始的版本几乎快了一倍多,这还是任务较少的情况下,如果任务较多情况会更加的明显。

你们以为这就完了么?既然大家都这么熟悉的份上,我再告诉大家一个效率更高的并发编程的方法,那就是 多进程+协程 的模式,我相信看了上面的分享,爱动手的你们一定可以自己动手写出来,写出来以后请在评论区给我留言哦。

学 Python ≠ 100G 视频资料

学 Python ≠ 傻瓜式的在线填空题

只有多写实操项目,才能学的高效。只有建立自己的知识体系,才能学的踏实。

这是我们一直在强调的学习方法,试过的人都学成了,没听进去的人都吃亏了。于是这一次,我们把学习方法做进了课程体系里。

学习顺序按照「学习-测评-实操」进行,强制你多写代码多练习,让你学的高效。

课程按照「建立知识模型-用法必知必会-上手项目案例-系统学习脑图」的知识体系,逐个模块系统递进,既有完整实操项目从零到上线,又有系统脑图的体系化,让你学的踏实。

这是只在「Python 后端工程师培养计划」才有的学习体验。

查看课程目录、免费试听:Python 后端工程师培养计划​www.mugglecode.com

python和易语言爬虫速度_如何优化 Python 爬虫的速度?相关推荐

  1. python和易语言哪个好学_易语言好用还是python语言好用?

    展开全部 python适合做框架程序,就是把其他编程语言的程序组合起来.e69da5e887aa62616964757a686964616f31333431376535不要用python做太多行的代码 ...

  2. python程序占用内存高_如何优化Python占用的内存,面试必学

    如果程序处理的数据比较多.比较复杂,那么在程序运行的时候,会占用大量的内存,当内存占用到达一定的数值,程序就有可能被操作系统终止,特别是在限制程序所使用的内存大小的场景,更容易发生问题.下面我就给出几 ...

  3. python和易语言抓包_易语言调用抓包工具 易语言网页抓包教程

    如何用易语言在手机上进行编程?需要用什么软件? 目前,有许多编程语言.当然,所有的句子都是由简单的英语单词组成的,而汉字是唯一简单的语言. 建议您也应该先学习C语言,开始学习if else,while ...

  4. python和易语言抓包_抓包能获取到网页源码,用易语言却获取不到,如何解决?...

    [Asm] 纯文本查看 复制代码.版本 2 .支持库 spec .程序集 窗口程序集_启动窗口 .子程序 _按钮1_被单击 .局部变量 a, 文本型 .局部变量 网址, 文本型 .局部变量 b, 文本 ...

  5. python人工智能是什么意思_人工智能和python有什么关系?

    展开全部 Python是一门脚本语2113言,它更适合去做人工智能这个领域5261,在人工智能上使用4102Python比其他编程语言有更大1653的优势. 现在人工智能爆发,学习一门python语言 ...

  6. python语言学完后学什么_学完Python语言可以做什么?发展前景怎么样?

    Python是一门高级的编程语言,其语言功能强大.语法简单.上手容易,因此受到了不少人的喜欢.而对于学习一门语言,很多人最看重的就是,学习之后可以做什么?有哪些岗位?薪资待遇如何?为大家详细的讲解一下 ...

  7. python将字符串逆序_为什么说Python是一门伟大的入门语言?(附免费教程)

    Python 是一门伟大的入门语言.作为一门伟大的编程语言,一定要具备一些特征,其中有五项特征是非常重要的: 非常棒的首次体验:就像书的开始,首先一定要能够"沉迷",学习新知识一定 ...

  8. 网络爬虫python的特点有哪些_为什么写网络爬虫天然就是择Python而用

    关于这个问题,老猿就先从自己的经历讲起吧.很多年前,大约11年前,老猿我接手了一个搜索引擎的网络爬虫,那是一个用C++写的通用搜索引擎的爬虫.C++的语言,多线程的实现,爬虫的运行效率非常高.但是,找 ...

  9. python分布式爬虫系统_三种分布式爬虫系统的架构方式

    分布式爬虫系统广泛应用于大型爬虫项目中,力求以最高的效率完成任务,这也是分布式爬虫系统的意义所在. 分布式系统的核心在于通信,介绍三种分布式爬虫系统的架构思路,都是围绕通信开始,也就是说有多少分布式系 ...

最新文章

  1. 初涉网络实验-路由器端口的开启与配置
  2. php7安装event拓展
  3. NYOJ 23 取石子(一)
  4. 设计模式随笔系列:鸭子-策略模式(Strategy)
  5. linux TCP数据包封装在SKB的过程分析
  6. 【英语学习】【WOTD】zero-sum 释义/词源/示例
  7. 图像超分辨率重构(一)原理及方法总结
  8. springSecurity jwt 认证与鉴权及异常
  9. Python--sort()函数的用法
  10. Intouch | 报警延时设定
  11. js回避ie缓存的办法
  12. 次梯度(subgradient)方法
  13. Java8新特性之Joining
  14. 『NLP经典项目集』10:使用预训练模型优化快递单信息抽取
  15. 文件管理功能重构,MeterSphere开源持续测试平台v2.1.0发布
  16. 视网膜电图特征可以检测成人的抑郁状态和治疗反应:一种机器学习方法
  17. 如何设计一触式微交互
  18. 我们一起学 ABAP (01) ~ 初识SAP ABAP
  19. 我不情愿的用了20多分钟,满足了学姐的要求,可是...
  20. 笔记代码 | 统计学——基于R(第四版) 第一章

热门文章

  1. Android 图片圆角的设置
  2. eclipse 矩阵删除行列,也可以矩阵形式编辑
  3. Spring 核心控制器DispatcherServlet(二)
  4. css模拟select设置高度在ie67下有效(也可作为去除边框)
  5. GAE 博客——B3log Solo 0.3.0 正式版发布了!
  6. 小量数据和海量数据分页显示存储过程
  7. visual basic对文件夹下的excel执行批量删除行操作
  8. puml绘制思维导图_定制工作计划有哪些操作,4款工作思维导图模板助你效率蹭蹭上涨...
  9. 对于SQL注入的理解
  10. 【洛谷 P1772】 [ZJOI2006]物流运输(Spfa,dp)