Python使用协程进行爬虫
详情点我跳转
关注公众号“轻松学编程”了解更多。
1、协程
协程,又称微线程,纤程。英文名Coroutine。
协程是啥 ??
首先我们得知道协程是啥?协程其实可以认为是比线程更小的执行单元。为啥说他是一个执行单元,因为他自带CPU上下文。这样只要在合适的时机,我们可以把一个协程切换到另一个协程,只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的。
通俗的理解:在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行,注意不是通过调用函数的方式做到的,并且切换的次数以及什么时候再切换到原来的函数都由开发者自己确定。
协程和线程差异
最大的优势就是协程极高的执行效率,因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销线程切换从系统层面远不止保存和恢复 CPU上下文这么简单。操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。
第二大优势协程就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突。
2、使用协程
1.使用greenlet + switch实现协程调度
'''
使用greenlet + switch实现协程调度
'''
from greenlet import greenlet
import time
def func1():
print("开门走进卫生间")
time.sleep(3)
gr2.switch() # 把CPU执行权交给gr2
print("飞流直下三千尺")
time.sleep(3)
gr2.switch()
pass
def func2():
print("一看拖把放旁边")
time.sleep(3)
gr1.switch()
print("疑是银河落九天")
pass
if __name__ == '__main__':
gr1 = greenlet(func1)
gr2 = greenlet(func2)
gr1.switch() # 把CPU执行权先给gr1
pass
输出:
开门走进卫生间
一看拖把放旁边
飞流直下三千尺
疑是银河落九天
2.使用gevent + sleep自动将CPU执行权分配给当前未睡眠的协程
'''
使用gevent + sleep自动将CPU执行权分配给当前未睡眠的协程
'''
import gevent
def func1():
gevent.sleep(1)
print("大梦谁先觉")
gevent.sleep(13)
print("1:over")
pass
def func2():
gevent.sleep(3)
print("平生我自知")
gevent.sleep(9)
print("2:over")
pass
def func3():
gevent.sleep(5)
print("草堂春睡足")
gevent.sleep(5)
print("3:over")
pass
def func4():
gevent.sleep(7)
print("窗外日迟迟")
gevent.sleep(1)
print("4:over")
pass
def simpleGevent():
gr1 = gevent.spawn(func1)
gr2 = gevent.spawn(func2)
gr3 = gevent.spawn(func3)
gr4 = gevent.spawn(func4)
gevent.joinall([
gr1, gr2, gr3, gr4
])
if __name__ == '__main__':
simpleGevent()
pass
输出:
大梦谁先觉
平生我自知
草堂春睡足
窗外日迟迟
4:over
3:over
2:over
1:over
3.通过monkey调度
'''
使用gevent + monkey.patch_all()自动调度网络IO协程
'''
import gevent
import requests
import time
from gevent import monkey
def getPageText(url, order=0):
print("No%d:%s请求开始..." % (order, url))
resp = requests.get(url) # 发起网络请求,返回需要时间——阻塞IO
html = resp.text
print("No%d:%s成功返回:长度为%d" % (order, url, len(html)))
pass
# 将【标准库-阻塞IO实现】替换为【gevent-非阻塞IO实现】
monkey.patch_all()
if __name__ == '__main__':
start = time.time()
time.clock()
# 协程传递参数,(方法名,参数。。。)
gevent.joinall([
gevent.spawn(getPageText, "http://www.sina.com", order=1),
gevent.spawn(getPageText, "http://www.qq.com", order=2),
gevent.spawn(getPageText, "http://www.baidu.com", order=3),
gevent.spawn(getPageText, "http://www.163.com", order=4),
gevent.spawn(getPageText, "http://www.4399.com", order=5),
gevent.spawn(getPageText, "http://www.sohu.com", order=6),
gevent.spawn(getPageText, "http://www.youku.com", order=7),
gevent.spawn(getPageText, "http://www.iqiyi.com", order=8),
])
end = time.time()
print("over,耗时%d秒" % (end - start))
print(time.clock())
pass
后记
【后记】为了让大家能够轻松学编程,我创建了一个公众号【轻松学编程】,里面有让你快速学会编程的文章,当然也有一些干货提高你的编程水平,也有一些编程项目适合做一些课程设计等课题。
也可加我微信【1257309054】,拉你进群,大家一起交流学习。
如果文章对您有帮助,请我喝杯咖啡吧!
公众号


关注我,我们一起成长~~
Python使用协程进行爬虫的更多相关文章
- python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用
python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用 一丶单线程+多任务的异步协程 特殊函数 # 如果一个函数的定义被async修饰后,则该函数就是一个特殊的函数 async ...
- {python之协程}一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二
python之协程 阅读目录 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本 ...
- 【python】-- 协程介绍及基本示例、协程遇到IO操作自动切换、协程(gevent)并发爬网页
协程介绍及基本示例 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他 ...
- python gevent 协程
简介 没有切换开销.因为子程序切换不是线程切换,而是由程序自身控制,没有线程切换的开销,因此执行效率高, 不需要锁机制.因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断 ...
- 深入理解Python中协程的应用机制: 使用纯Python来实现一个操作系统吧!!
本文参考:http://www.dabeaz.com/coroutines/ 作者:David Beazley 缘起: 本人最近在学习python的协程.偶然发现了David Beazley的co ...
- 关于Python的协程问题总结
协程其实就是可以由程序自主控制的线程 在python里主要由yield 和yield from 控制,可以通过生成者消费者例子来理解协程 利用yield from 向生成器(协程)传送数据# 传统的生 ...
- 【Python】协程
协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在 ...
- Python之协程(coroutine)
Python之协程(coroutine) 标签(空格分隔): Python进阶 coroutine和generator的区别 generator是数据的产生者.即它pull data 通过 itera ...
- python的协程和_IO操作
协程Coroutine: 协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行. 注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点 ...
随机推荐
- windows 漏洞列表
漏洞列表 #Security Bulletin #KB #Description #Operating System CVE-2017-0213 [Windows COM Eleva ...
- MATLAB中exist函数的用法
exist:exist主要有两种形式,一个参数和两个参数的,作用都是用于确定某值是否存在:1. b = exist( a) 若 a 存在,则 b = 1: 否则 b = 0:2. b = e ...
- phpstorm中配置使用svn详细步骤
一.搭建SVN环境 1.下载VisualSVN Sever.下载地址:https://www.visualsvn.com/server/download/ 2.安装VisualSVN Server. ...
- shell-脚本的建立和执行
1. shell脚本的建立和执行 1) shell脚本的建立 在linux系统中,shell脚本(bash shell程序)通常是在编辑器(如vi/vim)中编写,由unix/linux命令.bas ...
- background-size 详解
backgroun-size:cover; .是按照等比缩放铺满整个区域.主要用于图片比div小的时候,将图片按照某一边的比例扩大以填充整个div背景. .优点:图片不会被拉升,且实用于div长度和宽 ...
- DBA提交脚步规范
工作中需要走脚步流程,申请修改数据库,总结一些常用的语句:)提交时注明为DDL/DML_需求号_日期(各公司标准不一样)//修改字段长度使用;alter table t_task modify tas ...
- Python+Appium自动化测试(2)-appium连接真机启动app
app自动化测试的第一步,是启动被测app.appium环境搭建好后,我们就可以连接真机启动app了.环境为windows,Appium1.18.0,Android手机,被测app为今日头条app,让 ...
- arcgis-java-100.8.0.jar下载
链接: https://pan.baidu.com/s/1HoW2IhPvHRw9LBZphxC5Rw 提取码: pexn
- 解读JVM虚拟机
概要点: java虚拟机概述和基本概念 堆.栈.方法区 了解虚拟机参数 垃圾回收概念和算法.及对象的分代转换 垃圾收集器 java虚拟机的原理: 所谓虚拟机,就是一台虚拟的机器.它是一款软件,用来执行 ...
- C 和 C++ 打起来了!曾今最亲密的伙伴到现今的不爽?
70年代初,贝尔实验室创建了C语言,它是开发UNIX的副产品.很快C就成为了最受欢迎的编程语言之一.但是对于Bjarne Stroustrup来说,C的表达能力还不够.于是,他在1983年的博士论文中 ...