用协程做的简单爬虫 - downtiser/python-one GitHub Wiki
urllib
模块来建立和指定网页的连接,主要不是为了爬网页,而是测试使用协程和串行时的效率差别,同时要注意得使用gevent
中的monkey
模块来给urllib
打补丁,否则gevent
会识别不到urllib
的I/O操作
下面这个脚本通过导入#Downtiser
from urllib import request
import gevent, time
from gevent import monkey #用于给urllib打补丁,使得gevent能够识别到urllib中的I/O操作
monkey.patch_all() #一键打补丁
url_list = ['https://www.google.cn', 'https://www.baidu.com', 'https://cn.bing.com']
def spider(url):
print('正在爬 [%s] .....'%url)
response = request.urlopen(url) #建立网络连接实例
data = response.read() #获取网页数据
print('[%s]网页的数据大小为 %s bytes'%(url, len(data)))
if __name__ == '__main__':
start_time = time.time()
for url in url_list:
spider(url)
print('串行cost>>> %s sec'%(time.time()-start_time))
async_start_time = time.time()
gevent.joinall([
gevent.spawn(spider,'https://www.google.cn',),
gevent.spawn(spider, 'https://www.baidu.com',),
gevent.spawn(spider, 'https://cn.bing.com',)
])
print('异步cost>>> %s sec'%(time.time()-async_start_time))
结果>>>
正在爬 [https://www.google.cn] .....
[https://www.google.cn]网页的数据大小为 3213 bytes
正在爬 [https://www.baidu.com] .....
[https://www.baidu.com]网页的数据大小为 227 bytes
正在爬 [https://cn.bing.com] .....
[https://cn.bing.com]网页的数据大小为 117009 bytes
串行cost>>> 0.7503583431243896 sec
正在爬 [https://www.google.cn] .....
正在爬 [https://www.baidu.com] .....
正在爬 [https://cn.bing.com] .....
[https://www.baidu.com]网页的数据大小为 227 bytes
[https://www.google.cn]网页的数据大小为 3213 bytes
[https://cn.bing.com]网页的数据大小为 117009 bytes
异步cost>>> 0.4545109272003174 sec
从结果可以看出,使用异步操作在仅有三个网页的情况下耗时就只有串行的一半,当爬取大量网页时,协程异步的优势会更明显