下载中间件的作用
下载中间件是scrapy提供用于用于在爬虫过程中可修改Request和Response,用于扩展scrapy的功能;比如:
- 可以在请求被Download之前,请求头部加上某些信息;
- 完成请求之后,回包需要解压等处理;
下载中间件和管道一样根据优先级执行,
- 当request从引擎向下载中间建传的时候,数字小的先执行,
- 当response从下载器向引擎传递的时候,数字大的先执行
一些自带的下载器中间件
#
DOWNLOADER_MIDDLEWARES_BASE =
{
'scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware': 100,
'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware': 300,
'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware': 350,
'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware': 400,
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': 500,
'scrapy.downloadermiddlewares.retry.RetryMiddleware': 550,
'scrapy.downloadermiddlewares.ajaxcrawl.AjaxCrawlMiddleware': 560,
'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware': 580,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 590,
'scrapy.downloadermiddlewares.redirect.RedirectMiddleware': 600,
'scrapy.downloadermiddlewares.cookies.CookiesMiddleware': 700,
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 750,# 设置代理的中间件
'scrapy.downloadermiddlewares.stats.DownloaderStats': 850,
'scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware': 900,
}
写自己的下载中间件
下载器中间件是一个类,类里可以定义方法,列如 process_request()
,process_response()
,process_exception()
一般来说这三个方法是常用的。
process_request(request,spider)
对请求做处理的方法,参数是 request , spide, request是个字典,字典里包含了headers,url等,process_request典型的任务是修改user-agent,变换代理
当每个Request对象经过下载中间件时会被调用,**优先级越高的中间件,越先调用;**该方法应该返回以下对象:None
/ Response
对象 / Request
对象 / 抛出IgnoreRequest
异常;
- 返回
None
:scrapy会继续执行其他中间件相应的方法; - 返回
Response
对象:当直接通过url发送请求后返回,scrapy不会再调用其他中间件的process_request
方法,也不会去发起下载,而是直接返回该Response
对象给引擎,已激活的中间件的 process_response()方法则会在 每个 response 返回时被调用; - 返回
Request
对象:当对请求做了修改时返回,并且scrapy不会再调用其他中间件的process_request()
方法,而是将其放置调度器,等待调度下载; - 抛出
IgnoreRequest
异常:已安装中间件的process_exception()
会被调用,如果它们没有捕获该异常,则Request.errback
会被调用;如果再没被处理,它会被忽略,且不会写进日志。
process_response(request, response, spider)
对响应处理,该方法返回以下对象:Response
对象/Request
对象/抛出IgnoreRequest
异常。
- 返回
Response
对象:scrapy会继续调用其他更低优先级的中间件的process_response
方法,对response处理; - 返回
Request
对象:更低优先级的下载中间件的 process_response方法不会继续调用,将request其放置到调度器,等待调度下载; - 抛出
IgnoreRequest
异常:Request.errback
会被调用来处理函数,如果没有处理,它将会被忽略且不会写进日志。
process_exception(request, exception, spider)
当process_exception()
和process_request()
抛出异常时会被调用,应该返回以下对象:None
/ Response
对象 / Request
对象;
- 如果返回
None
:scrapy会继续调用其他中间件的process_exception()
; - 如果返回
Response
对象:中间件链的process_response()
开始启动,不会继续调用其他中间件的process_exception()
; - 如果返回
Request
对象:停止中间器的process_exception()
方法调用,将其放置到调度器待调度下载。
常见应用
首先呢还是先建项目,爬虫
scrapy startproject xiazaizjj #创建项目
scrapy genspider zjj "httpbin.org" # 在spiders 目录下创建爬虫文件
现在来写一下爬虫文件
###### zjj.py
# -*- coding: utf-8 -*-
import scrapy
class ZjjSpider(scrapy.Spider):
name = 'zjj'
allowed_domains = ['httpbin.org']
start_urls = ['http://httpbin.org/get']
def parse(self, response):
print(response.text)
print(response.status)
什么都不做,运行一下 scrapy crawl zjj
下面开始操作一波
1.随机变换请求头
在中间件的文件中 middlewares.py
写下载中间件
# -*- coding: utf-8 -*-
# Define here the models for your spider middleware
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/spider-middleware.html
import random
from scrapy import signals
class XiazaizjjSpiderMiddleware(object):
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the spider middleware does not modify the
# passed objects.........
# 下面这个是我们要改的下载中间件
# 把它自动生成的注释删了,然后修改就好了
class XiazaizjjDownloaderMiddleware(object):
def __init__(self):
self.use_agent = [
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
]
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request, spider):
request.headers['User-Agent'] = random.choice(self.use_agent)
def process_response(self, request, response, spider):
# 改一下返回的状态码看看
response.status = 203
return response
def process_exception(self, request, exception, spider):
# 这个我们没有用到,不管它,删了也可以
pass
def spider_opened(self, spider):
spider.logger.info('Spider opened: %s' % spider.name)
在settings.py文件中打开我们的下载中间件
DOWNLOADER_MIDDLEWARES = {
'xiazaizjj.middlewares.XiazaizjjDownloaderMiddleware': 543,
}
再运行一下,我们可以看到,已经发生了改变
2.设置代理
只用在刚才的代码后面加上这个就可以了,之后就会随机选择代理的ip 但是这个代理ip就只有一会有用,如果可以大家可以买几个稳定的,这里就不买了,
class ProxyMiddleware(object):
proxy_list = [
"http://120.234.138.101:53779",
"http://171.35.173.250:9999",
]
def process_request(self,request,spider):
ip = random.choice(self.proxy_list)
request.meta['proxy']=ip
同样要打开这个下载中间建,优先级设置一下,目前大小没关系
然后运行,我们会发现 ip改变了,这里就不截图了,
下次我们将学习爬虫中间件和管道的详细说明
我又来要赞了,还是希望各位路过的朋友,如果觉得可以学到些什么的话,点个赞再走吧,欢迎各位路过的大佬评论,指正错误,也欢迎有问题的小伙伴评论留言,私信。每个小伙伴的关注都是我更博的动力》》》》奥里给