上一篇博客中我介绍了如何将爬虫改造为多进程爬虫,但是这种方法对爬虫效率的提升不是非常明显,而且占用电脑CPU较高,不是非常适用于爬虫。这篇博客中,我将介绍在爬虫中广泛运用的多线程+协程的解决方案,亲测可提高效率至少十倍以上。
一、概念介绍
1、进程
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。
2、线程
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。
3、协程
二、代码
多线程可以使用的包一般有两个:和,更强大和常用一点,可以利用来自定义多线程类。为下的协程包。
本篇实例场景与上一篇相同,依旧为爬取外文数据库,可参考Python爬虫——多进程multiprocessing
其中是自定义的线程类,传入参数为列表。在这个线程类中开启多个协程。
在上述代码中我开启了6个线程,并且在每个线程中开启了20个协程,因为需要抓取的数据量较大,故对数据进行了切割。其实也可以使用队列的方式来实现,多个协程共用同一个队列数据,但是管理起来稍微麻烦一点。
我在运行的过程中发现有这样几个问题,运行速度很快,是多进程的十几倍,但是抓很多数据时会抓取失败,报各种错误,最常见的是之类的错误,应该是每个协程都获得了一个文件的句柄,所以你可能只打开了几个文件,但是系统会认为你开启了很多,网上找了解决方案(有一个是修改,即系统设定的最大开启文件数量,在下输入得到的1024是系统默认的,可以通过修改为5000,但是也没能解决问题),但是都没有很好的方法能避免这类问题,希望懂的高手能够告知一下。
多线程+协程的方法效率高,但是很不稳定,会出现很多错误,所以在编写代码的过程中,需要做一些错误的处理,使程序更加robust,在抓取一些链接出问题的时候能够不挂掉继续抓取其他页面。建议将出错的url保存到一个文件内,最后再对这些url进行抓取。
我的urllist文件中其实有20万条数据,但是全部一次性运行会挂掉,所以我是每次读取4万条记录,然后6个线程,每个线程分别20个协程进行抓取,大概1小时搞定。
以上,欢迎交流,如有错误也欢迎指出。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/2194.html