C++,python,热爱算法和机器学习
全部博文(1214)
分类: Python/Ruby
2014-02-17 00:10:51
最近在做一个站点,需要在网络上收集一些资料。干这活用python很合适,于是就准备用gevent+requests实现一个爬虫。以前曾用gevent抓取过漫画,但那时的url都是先生成的,并非动态添加,所以需要解决gevent的动态添加任务的问题。
import gevent
from gevent import monkey
monkey.patch_all()
import requests
def down(url):
print len(requests.get(url).content)
urls = ['','']
spawns = []
for url in urls:
spawns.append(gevent.spawn(down, url))
gevent.joinall(spawns)
刚开始我就是用这种方式去下载的,但这种方式不能控制并发数,会将所有的urls一起请求。
使用gevent.pool模块可以控制下载并发。改过后的代码如下:
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 = ['','']
for url in urls:
p.spawn(down, url)
p.join()
在正常情况下如果执行了join函数那程序就不会再往下执行,必需等待下载任务完成。写爬虫的时候需要处理页面信息并将解析出来的url动态的添加到下载任务当中,查看gevent的文档后发现使用gevent.core和gevent.Greenlet就可以实现这个功能。
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 = ['','']
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()