学习爬虫有一段时间了,期间接触了很多相关的库,不禁感慨Python就是强大,当你遇到任何问题的时候基本上都有前人造好的轮子,只要直接 import 就行了。在此把爬虫相关的库及方法做个简单的总结,也欢迎大家做补充。
一、引言
爬虫主要分为:网页采集、网页解析、数据存储、数据分析这么几步,每一步都有各自的难点。此外,为了提高爬虫的效率,程序的运行还可采用多进程、多线程、协程和分布式这么几种。目前流行的爬虫框架有scrapy、pyspider等。以下对相关类库做简单介绍。
二、网页采集
网页采集算是爬虫程序的核心了,因为在web技术飞速发展的今天,你面对的早已不再是一个不设防的静态网页的世界,取而代之的是一山更比一山高的反爬技术,处处使用ajax异步加载的网页,笔者资历尚浅,踩过的坑不多,在此就我使用过的一些库做些简单的介绍。
urllib模块
urllib 是 Python 自带的 web 模块,包含了平常我们使用的大多数功能。
值得一提的是 urllib 在 Python2 和 Python3 中有所不同,在此就不细说了。
urllib2文档 for python2.7
urllib文档 for python3.6
requests模块
requests是一个相对urllib而言更加人性化的模块,它支持 HTTP 连接保持和连接池,支持使用 cookie 保持会话,支持文件上传,支持自动确定响应内容的编码,支持国际化的 URL 和 POST 数据自动编码。
使用requests可以方便的对登录的账号使用session保持会话,此外还能自动解析gzip压缩的网页,十分强大。
requests文档
selenium模块
目前很多网页都使用异步加载的技术,一般都是通过抓包,分析出异步加载的链接,然后在对加载的数据进行解析,但是对于很多加密的异步链接,可能就需要很大的功夫才能破解。selenium 模块原来是用来做web测试的,它可以模拟不同浏览器,因此使用 selenium 模块,配合不同浏览器的 driver,就相当于在浏览器中打开链接,并可以对 dom 进行操作,加载异步的数据。
selenium文档
selenium支持IE、firefox、chrome、opera等浏览器,但是使用这些浏览器时往往会打开一个浏览器窗口,因此爬虫程序通常使用PhantomJS,它是一个基于WebKit的服务器端 JavaScriptAPI,相当于一个无界面浏览器。基于 selenium 和 PhantomJS 可以很简单的加载异步数据并依此对网页进行爬取。
三、网页解析
网页解析一般用的是 lxml 和 BeautifulSoup,当然BeautifulSoup也支持lxml解析。
lxml模块
lxml,使用 xpath 语法,解析速度快是它的优点。
lxml文档
BeautifulSoup模块
BeautifulSoup是一个功能强大的 HTML及XML解析模块,支持Python标准库中的HTML解析器,以及第三方的lxml解析器和html5lib解析器,功能强大而且语法人性化。
BeautifulSoup文档
四、数据存储
从网页采集到数据后,常常需要将数据保存进行分析,对于少量的数据,可以用 json /excel进行保存,而对于大量的数据,则必须使用数据库进行存储,数据库又分为两大类 SQL数据库和NoSQL数据库。常用的SQL数据库有:SQL Server、MySQL、Oracle等,常用的NoSQL数据库有MongoDb、Redis等。相应的,python也提供了相应的模块对数据库进行操作。
json模块
python使用自带模块 json, 对 json 数据进行操作。
json文档
xlwt模块 及 xlrd模块
xlwt 和 xlrd 都是 Python 操作excel文档的模块。
xlwt文档
xlrd文档
MySQLdb模块
MySQLdb 是 MySQL的 Python 接口开发包。
MySQLdb文档
PyMango模块
PyMango 是 MongoDB 的 Python 接口开发包。
PyMango文档
redis-py模块
redis-py 是 redis 的 Python 接口开发包。
redis-py文档
五、数据分析
数据分析是一个很大的范畴,涉及数据分析的模块太多了,在此就不一一介绍了,简单介绍几个常用的模块吧。
数值计算:NumPy和SciPy模块
NumPy是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多。
scipy函数库在NumPy库的基础上增加了众多的数学、科学以及工程计算中常用的库函数。例如线性代数、常微分方程数值求解、信号处理、图像处理、稀疏矩阵等等。
numpy和scipy文档入口
自然语言分析:结巴分词、NLTK模块
结巴中文分词是一个非常好用的中文分词组件,经过分析,语料就可以直接投入NLTK进行分析了。
NLTK工具集是目前最流行的自然语言分析模块
结巴分词文档
NLTK模块
图片处理:OpenCV、PIL、matplotlib模块
OpenCV、PIL、pillow、matplotlib 都是python对图片进行处理的模块,无论是对爬取的图片进行保存,还是对验证码进行识别,你难免都会用手它们,因为笔者使用较少,就不多介绍了。
OpenCV文档
PIL文档
pillow文档
matplotlib官网
六、效率提升
一般爬虫程序耗时的过程都不是计算,大部分是在应对反爬(例如单IP一小时限制爬取次数)、网络请求响应、数据库IO上。而如何提升爬虫的效率,无疑是后期一个爬虫工程师所关注的重点,一般可以使用多进程、多线程、异步IO、分布式来优化爬虫,各自方法有各自的优点和适用范围。
多进程
要实现高并发,直接开多个任务分配给几个进程当然是最简单的方法,multiprocessing提供了Python对多进程的支持。
multiprocessing文档
多线程
多进程开销大,同样也可以使用多线程对爬虫程序进行改进,multiprocessing也提供了多线程的接口,此外还有thread和threading模块,thread是低级模块,threading是高级模块,对thread进行了封装。绝大多数情况下,我们只需要使用threading这个高级模块。
threading文档
协程及异步IO
其实对于网络编程,多进程和多线程都不是特别好的解决方法,因为网络请求是阻塞的,这也意味着一个任务,可能你要用90%的时间用来等待网络请求的返回,如果能用等待网络请求的时间进行后续操作,这将节省很多时间。于是就有了异步IO这种解决方案。加上Python3.5以后 async/await 等语法的加入,对异步的支持也越来越强大,所以相信以后异步的库也会越来越多。
gevent
gevent为Python提供了比较完善的协程支持。gevent是第三方库,通过greenlet实现协程,其基本思想是:当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。
gevent 文档
asyncio
asyncio作为一个python3.4引入的标准库,提供了异步IO的解决方案,而且在python3.5、3.6两个版本中都对asyncio增加了更多的支持,其功能也越来越强大。
asyncio文档
aiohttp
我一直把aiohttp当成是异步版的requests库,易用性强,加上对异步的支持,我觉得已经可以抛弃对python3支持不好的twisted库了。
aiohttp文档
分布式
严格意义上说,分布式应该算是一种架构,其思想就是用一些机器作为master,一些机器作为slaver,master分配任务给slaver,这样就实现了爬虫在不同机器上分别进行,提高效率。分布式最强大的地方在于,它能最有效突破IP的限制,这是前几种爬虫很难达到的(当然,你可以说用代理池,我认为代理池也可以算是分布式的一种特例)。
笔者用的最多是用redis数据库作为任务的分配中心,因为redis操作具有原子性,而且redis基于内存,访问速度极快。
redis-py文档
七、爬虫框架
目前应用较多的爬虫框架有Scrapy、pyspider,其中,每个框架还有各自的扩展。
scrapy
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,相信写过爬虫的没有不知道它的。值得一提的是,scrapy是基于twisted异步框架实现的,也就是说,scrapy本身是异步IO的。
scrapy文档
因为 scrapy 的强大,很多开发者对 scrapy 进行了扩展,常用的有:scrapy-redis、scrapy-splash
scrapy-redis
scrapy-redis是基于scrapy 和 redis 实现的分布式爬虫拓展
scrapy-redis文档
scrapy-splash
splash与phantomjs类似,是基于Twisted和QT开发的轻量浏览器引擎,scrapy-splash 对异步加载网页提供了高效的支持
scrapy-splash文档
pyspider
一个国人编写的强大的网络爬虫系统并带有强大的WebUI。采用Python语言编写,分布式架构,支持多种数据库后端,强大的WebUI支持脚本编辑器,任务监视器,项目管理器以及结果查看器。
pyspider官网