Scrapy有两种中间件,Downloader Middleware和Spider Middleware。我们来讲讲用的最多的Downloader Middleware。
在爬虫开发中,更换代理IP是非常常见的情况,有时候甚至每一次访问都需要随机选择一个代理IP来进行。我们以更换代理IP为例来讲解如何开发一个中间件。
中间件本身是一个Python的类,更换IP是在访问每个网页之前。所以,会用到process_request方法,这个方法中的代码会在每次爬虫访问网页之前执行。请看下面的代码:
这两个类UAMiddleware和ProxyMiddleware实现了在每次访问网页的时候更换User-Agent和代理IP。我将备选的User-Agent和代理IP写在了settings.py文件中,如下图所示:
当然,你也可以将它们写到数据库或者Redis中。
所以,我们的爬虫系统可以这样写:
写一个小爬虫ProxySpider去各大代理网站爬取免费代理并验证。将可以使用的代理IP保存到数据库中。
在ProxyMiddlerware的process_request中,每次从数据库里面随机选择一条代理IP地址使用。
周期性验证数据库中的无效代理,及时将其删除。
middlewares.py的文件名,以及ProxyMiddleware这个类名你改成其他的也可以,不过一般约定俗成这样写,类名统一使用“功能Middleware”例如:UserAgentMiddleware, CookieMiddleware, ProxyMiddleware...
虽然中间件已经写好了,我们现在需要让Scrapy使用它。大家在Scrapy的settings.py中找找有没有这样一段被注释掉的话:
# Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
# DOWNLOADER_MIDDLEWARES = {
# 'ComplexDisSpider.middlewares.MyCustomDownloaderMiddleware': 543,#}
我们把这几段解除注释,再将其中的:
ComplexDisSpider.middlewares.MycustomDownloaderMiddleware
修改为:
ComplexDisSpider.middleware.ProxyMiddleware
这样,Scrapy在每次访问网页的时候,就会更换代理IP了。
后面的数字表示优先级。数字越小,优先级越高,越先执行。例如如果你有一个更换代理的中间件,还有一个更换Cookie的中间件,那么更换代理的中间件显然是需要在更换Cookie的中间件之前运行的。如果你把这个数字设为None,那么就表示禁用这个中间件。