文章目录
  1. 1. 普通的gevent下载方式
  2. 2. gevent.pool控制并发
  3. 3. 动态添加下载地址

最近在做一个站点,需要在网络上收集一些资料。干这活用python很合适,于是就准备用gevent+requests实现一个爬虫。以前曾用gevent抓取过漫画,但那时的url都是先生成的,并非动态添加,所以需要解决gevent的动态添加任务的问题。

普通的gevent下载方式

1
2
3
4
5
6
7
8
9
10
11
12
13
import gevent
from gevent import monkey
monkey.patch_all()
import requests

def down(url):
print len(requests.get(url).content)
urls = ['http://www.baidu.com','http://www.sina.com.cn']
spawns = []
for url in urls:
spawns.append(gevent.spawn(down, url))

gevent.joinall(spawns)

刚开始我就是用这种方式去下载的,但这种方式不能控制并发数,会将所有的urls一起请求。

gevent.pool控制并发

使用gevent.pool模块可以控制下载并发。改过后的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import gevent
from gevent import monkey
monkey.patch_all()
from gevent.pool import Pool
import requests

p = Pool(2)#设置并发数为2
def down(url):
print len(requests.get(url).content)

urls = ['http://www.baidu.com','http://www.sina.com.cn']
for url in urls:
p.spawn(down, url)

p.join()

动态添加下载地址

在正常情况下如果执行了join函数那程序就不会再往下执行,必需等待下载任务完成。写爬虫的时候需要处理页面信息并将解析出来的url动态的添加到下载任务当中,查看gevent的文档后发现使用gevent.core和gevent.Greenlet就可以实现这个功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import gevent
from gevent import monkey, Greenlet
monkey.patch_all()
from gevent.pool import Pool
import requests

p = Pool(2)#设置并发数为2
def down(url):
print len(requests.get(url).content)

urls = ['http://www.baidu.com','http://www.sina.com.cn']
for url in urls:
p.spawn(down, url)

def buildurl():
while True:
gevent.sleep(0)#添加这条后才可以切换到其它任务
print u"检测下载地址"#这里可以动态添加下载任务

Greenlet.spawn(buildurl)
loop = gevent.core.loop()
loop.run()

tip

buildurl里面的操作不要有长时间阻塞的,会影响程序运行的。loop.run()是在gevent1.0以上的版本里才有的,以下版本请直接运行buildurl()

文章目录
  1. 1. 普通的gevent下载方式
  2. 2. gevent.pool控制并发
  3. 3. 动态添加下载地址