用协程做的简单爬虫 - 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

从结果可以看出,使用异步操作在仅有三个网页的情况下耗时就只有串行的一半,当爬取大量网页时,协程异步的优势会更明显