使用协程(gevent)实现请求
协程,又称微线程。英文名Coroutine。
协程最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。
第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。
因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。后续会就这一块单独开写一篇协程+多进程的测试文章。
Python对协程的支持还非常有限,用在generator中的yield可以一定程度上实现协程。虽然支持不完全,但已经可以发挥相当大的威力了。
Python通过yield提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。
gevent是第三方库,通过greenlet实现协程,其基本思想是:
当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。
由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成:
所以在导入库的时候就要导入以下的库,这样子才可以实现交替运行机制,否则就都还是顺序运行机制
from gevent import monkey; monkey.patch_all()
以下是窒执行协程的一个代码,代码不多,只是几行代码而已
# urls = ['www.google.com', 'www.example.com', 'www.python.org']
# #使用的列表解析的方式形成list,而是不需要使用for和append的冗余代码区生成,简洁
# jobs = [gevent.spawn(socket.gethostbyname, url) for url in urls]
# gevent.joinall(jobs, timeout=2)
# print [job.value for job in jobs]
以下是使用协程抓取的一个电话号码的信息
# -*- coding:utf-8 -*-
import requests
from lxml import etree
import gevent
import MySQLdb
import datetime
class huoqu(object):
def __init__(self):
self.conn=MySQLdb.connect(
host='localhost',
port=3306,
user='root',
passwd='',
db='cai',
charset='utf8' )
self.cur=self.conn.cursor()
self.sql='insert into t_number_pass values(%s,%s,%s,%s,%s,%s)'
self.Add_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
def parse(self,pid):
base_url='http://www.139018.com/ReportList_'
url=base_url+str(pid+1)
print url
response=requests.get(url)
#print response.text
#/li[class="GlbBtmLn"]/div[[@class="Num"]/text()
selector=etree.HTML(response.text)
number=selector.xpath('//li/div[@class="Num"]/text()')
type=selector.xpath('//li/div[@class="RptTp"]/text()')
person=selector.xpath('//li/div[@class="Uper"]/text()')
subtime=selector.xpath('//li/div[@class="UpTm"]/text()')
text=selector.xpath('//li/div[@class="Txt"]/text()')
for i in range(len(number)):
self.cur.execute(self.sql,(number[i].encode('utf-8'),type[i].encode('utf-8'),person[i].encode('utf-8'),str(subtime[i].encode('utf-8')),text[i].encode('utf-8'),str(self.Add_time)))
self.conn.commit()
print number
print type
print person
print subtime
print text
def asynchronous(self):
threads=[]
for i in range(6043):
threads.append(gevent.spawn(self.parse,i))
gevent.joinall(threads)
def close_sql(self):
self.cur.close()
self.conn.close()
asy=huoqu()
asy.asynchronous()
asy.close_sql()
使用协程(gevent)实现请求的更多相关文章
- 协程:gevent模块,遇到i/o自动切换任务 038
协程 : gevent模块,遇到io自动切换任务 from gevent import monkey;monkey.patch_all() # 写在最上面 这样后面的所有阻塞就全部能够识别了 impo ...
- python编程中的并发------协程gevent模块
任务例子:喝水.吃饭动作需要耗时1S 单任务:(耗时20s) for i in range(10): print('a正在喝水') time.sleep(1) print('a正在吃饭') time. ...
- python---基础知识回顾(十)进程和线程(协程gevent:线程在I/O请求上的优化)
优点:使用gevent协程,可以更好的利用线程资源.(基于线程实现) 需求:使用一个线程,去请求多个网站的资源(注意,请求上会有延时)<实际上是去请求了大量的网站信息,我们使用了多线程,只不过每 ...
- 协程--gevent模块(单线程高并发)
先恶补一下知识点,上节回顾 上下文切换:当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行.这种 ...
- python2.0_s12_day9_协程&Gevent协程
Python之路,Day9 - 异步IO\数据库\队列\缓存 本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 协程 1.协程,又 ...
- python协程gevent案例:爬取斗鱼美女图片
分析 分析网站寻找需要的网址 用谷歌浏览器摁F12打开开发者工具,然后打开斗鱼颜值分类的页面,如图: 在里面的请求中,最后发现它是以ajax加载的数据,数据格式为json,如图: 圈住的部分是我们需要 ...
- 协程gevent
协程,利用线程在等待其他资源期间去执行其他的函数. gevent里面封装了greenlet,greenlet里面封装了yield. from gevent import monkey import g ...
- python之协程gevent模块
Gevent官网文档地址:http://www.gevent.org/contents.html 进程.线程.协程区分 我们通常所说的协程Coroutine其实是corporate routine的缩 ...
- Python协程 Gevent Eventlet Greenlet
https://zh.wikipedia.org/zh-cn/%E5%8D%8F%E7%A8%8B 协程可以理解为线程中的微线程,通过手动挂起函数的执行状态,在合适的时机再次激活继续运行,而不需要上下 ...
- yield、greenlet与协程gevent
yield 在说明yield之前,我们了解python中一些概念. 在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(ge ...
随机推荐
- ES6 imports用法
import defaultExport from "module-name"; import * as name from "module-name"; // ...
- zkfc的znode不存在的问题
cd /soft/hadoop/logs/hadoop-centos-zkfc-s101.log发现: 2018-09-29 12:42:03,616 FATAL org.apache.hadoop. ...
- ruby 条件判断&循环控制
参考:https://www.jb51.net/article/66709.htm
- 第8天 Java基础语法
第8天 Java基础语法 今日内容介绍 Eclipse开发工具 超市库存管理系统 Eclipse开发工具 Eclipse是功能强大Java集成开发工具.它可以极大地提升我们的开发效率.可以自动编译,检 ...
- 16-oauth2-oidc-Client实现
1-新建.net core2.1 mvc网站 2-在Startup.config文件增加相关代码, 下面代码已经配置好oidc客户端了,并设置本mvc启动ip为5009 public void Con ...
- 笔记-django第一个项目
笔记-django第一个项目 1. 创建项目 安装 Django 之后,现在有了可用的管理工具 django-admin.可以使用 django-admin 来创建一个项目: 看下djang ...
- 一个只有十行的精简MVVM框架(上篇)
本文来自网易云社区. 前言 MVVM模式相信做前端的人都不陌生,去网上搜MVVM,会出现一大堆关于MVVM模式的博文,但是这些博文大多都只是用图片和文字来进行抽象的概念讲解,对于刚接触MVVM模式的新 ...
- MySQL数据库优化方法
一.表类型MyISAM 和 InnoDB的区别 作者:Oscarwin链接:https://www.zhihu.com/question/20596402/answer/211492971来源:知乎著 ...
- 第三模块:面向对象&网络编程基础 第3章 选课系统作业讲解
01-选课系统作业讲解1 02--选课系统作业讲解2 03-选课系统作业讲解3 04--选课系统作业讲解4 01-选课系统作业讲解1 02--选课系统作业讲解2 03-选课系统作业讲解3 04--选课 ...
- 初学Direct X (2)
初学Direct X (2) 这一次要学习如何现实位图,尽管看过对双缓冲机制还有很多疑问,但是这并不阻碍我对他的入门了解 Direct3D提供了一个双重/后台缓冲区,在调用CreateDevice之时 ...