scrapy 集成到 django(三) - 代理中间件
项目地址: recruitment
中间件
虽然 代理 两字在前,但本文的重点是 中间件, 利用好了中间件,算是在掌握 scrapy 的道路上迈进了一大步.
首先看看 scrapy 的架构
如图所示:
详细的官方解释可参考: scrapy架构
在这里,我们注意到 Downloader-MiddleWare ,它是在 Request(请求) 和 Response(响应) 路上的一环.
假如你是一名间谍,要去到某个公司获取机密信息,但大摇大摆的过去肯定会被发现,这时候有个人告诉你,他可以给你弄一张门禁卡.这时候这个提供门禁的人起到的中间件的作用.
同样,在请求一些网页时,需要给请求加上 headers referer proxy 等信息,让自己的爬虫绕过反爬手段.同时,在当请求失败的时候及时处理错误的请求,而且在服务器响应部分还可以加以判断,看看服务器是否返回了正确的内容回来
中间件的文档可参考: Downloader-MiddleWare
文档已经说的很详细了,这里简单介绍下吧
一个 Downloader-MiddleWare 包含了 3 个主要的部分
# 处理请求的函数
def process_request(request, spider):
pass
# 处理响应的函数
def process_response(request, response, spider):
pass
# 处理错误的函数
def process_exception(request, exception, spider):
pass
这里给出一份完整的代码供参考
middleware.py
class ProxyMiddleWare():
# 在请求中植入 UA 和 header
def process_request(self, request, spider):
# 给 request 添加一些参数
# 通常代理/UA在这里添加
ua = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
request.headers.setdefault("User-Agent", ua)
request.meta["dont_redirect"] = True
request.meta['download_timeout'] = 5
# 遇到问题重新构造请求
def process_exception(self, request, exception, spider):
# 重新构造 ua
ua = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
request.headers.setdefault("User-Agent", ua)
# 发送新请求
new_req = request.copy()
return new_req
def process_response(self, request, response, spider):
# 请求成功
# 则直接给 spiders 处理
if response.status == 200:
return response
# 请求失败
# 则重新构造请求
else:
# 重新构造 ua
ua = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
request.headers.setdefault("User-Agent", ua)
# 发送新请求
new_req = request.copy()
return new_req
构造好自定义的中间件后,将其加入 settings.py 中
settings.py
DOWNLOADER_MIDDLEWARES = {
'project.middlewares.ProxyMiddleWare': 550
}
这样,在每一次请求时,都会自动加上一个 UA, 出现请求错误或者响应内容异常时会重新构造请求
代理中间件
刚刚讲了在中间件内添加 ua ,其实添加代理 ip 也是一样的道理,在网上购买或者自己爬取一些免费的代理,加入到中间件中即可.
这里就不贴代码了,愿意仔细研究的可以参考一下我的项目
这里推荐一个开源的 ip 池: IPProxyTool
然后我自己写的一个,水平不高,供参考: proxypool