python可以启动多少线程_多线程,多进程,分布式爬虫,一文说透

20ca6a309807f88904b5b9ab663140f3.png

本文不涉及具体的代码,仅仅是从理论上阐明加快爬虫爬取速度的各种方案,但接下来会专门写几篇文章,从技术实现上讲解加速的方案。

1. 小数据量爬取数据

如果你想要爬取的数据量并不大,充其量几百个页面,那么你丝毫没有必要考虑如何加快爬取速度,只需要启动爬虫脚本,然后耐心的等待即可。

之所以劝你不要考虑使用任何手段加快爬取速度,是因为采取这些手段本身就是一件耗时的事情,加大了你的编程难度,延长了你的调试时间,最终得不偿失。

2. 多线程加速

多线程加速是最简单有效的办法,程序编写并不复杂,但大多数人对于多线程究竟怎样做到加速的并不十分理解,有人甚至提醒说python的多线程由于有GIL锁,是伪多线程,多线程爬取没啥效果

这种观点对python多线程的描述是正确的,但结论是错误的。由于存在GIL锁,python中,一个时刻,只有一个线程在运行,但这不代表只有一个抓取任务在进行。

下图是一个线程在工作时的示意图

c914b0d431a13e495b9958700dc6749f.png
单个线程

python的进程通道非常狭小,因此,只允许一个线程通过,不过你不必担心,因为线程1并不总是占着通道,多个线程之间会以某种规则交替着占用这个通道,这时就会发生下面这张图里的情况

3d7ec74c2f08b21559fe589081f4ba3e.png
抢占GIL锁

线程2抢占了GIL锁,因此进入了进程通道,而线程1失去了线程锁,只能暂时挂起。

多线程爬取数据时,一个线程发起http请求后,有一段等待返回数据的过程,在这个时间段内,占用GIL锁的线程由于IO阻塞,就会交出GIL锁,这样别的线程就可以工作了,虽然一个时刻只能有一个线程工作,但是线程间的切换,充分利用了等待返回数据的这段时间,要明白,这个时间里,对于等待的线程是做不了任何事情的,交出GIL锁,让其他线程或发送http请求,或处理返回的结果。

在IO密集型任务中,python的多线程还是有一战之力的,但对于CPU密集型任务,由于不存在前面提到IO等待空闲时间,因此不能充分利用多线程进行工作。

3. 多进程加速

多进程加速相对多线程加速就容易理解了,毕竟人多力量大么,哪怕每个进程都采用单线程,也仍然可以加快爬取速度

eb05b66ffe6012401a45dde1fa9fb1f8.png
多进程,三车道

这就是马路上单车道和三车道的区别,马路越宽,可以通行的汽车数量越多啊。

4. 分布式爬虫

不要被分布式这三个字吓到了,本质上就是将任务的运行从一台机器扩展到多台机器,还是那个道理,人多力量大啊。

这个时候,你的代码自然也部署到多台机器上,那么是怎么部署的呢?太高级的技术你不会,你就一台机器一台机器手动部署呗,稍微高级一点,结合着fabric和git实现自动部署。

不管一台机器,还是多台机器,还是要落实到具体的进程上执行任务呀,假设一台机器上可以启动100个进程,那么10台机器就可以启动1000个进程,每个进程启动10个线程,那么一共就启动了1万个线程,假设每个线程2秒钟爬取一个网页,理论上,3秒钟你就可以爬取1万个网页了。

5. 任务分发

多线程,多进程,分布式,完全是不同层面的技术,但他们都有一个共同的问题要解决,那就是任务分发。

给你1万个网页让你爬取,你现在使用多线程技术,假设你启动了10个线程,那么问题来了,这1万个网页怎么分配呢,哪些给线程1抓取,哪些给线程2抓取?

如果你用多进程,还是要面临同样的问题,这些任务咋分配? 你用分布式,还是一样的问题,这么多台机器,咋分配?

其实,关于任务分发,有着非常成熟的方案,那就是消息队列,下图是消息队列的工作模式示意图

f199d5beb0fa12758dc419161126b47a.png

左侧是生产区域,中间是消息队列,右侧是消费区域,生产者将任务push(推送)到消息队列里,消息队列负责管理这些任务,右侧的消费者从消息队列里pull(拉取)任务进行消费。

生产者并不清楚这些任务都被谁消费了,消费者也并不清楚自己消费的任务是谁生产的,这样就实现了解耦。

回到爬虫这个问题上,你现在可以将那1万个网页的url推送到消息队列中,然后呢,消费端可以是多个线程,或者多个进程,或者多台机器上的进程,他们从消息队列里获取url,然后爬取数据保存数据。

关于消息队列,其实也并不难,有线程级别的消息队列,有进程级别的消息队列,还有redis,rabbitmq,这种小巧简单的消息队列,还有kafka这种工业级别的消息队列,他们的实现当然是天差地别,但工作模式本质上是一样的,就是上面那张图片所展示的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值