python爬虫 -08- 中间件(简单介绍和循环动态代理中间件)

process_request

在request对象传往downloader的过程中调用。当返回不同类型的值的时候,行为也不一样:

返回值行为
None一切正常,继续执行其他的中间件链
Response停止调用其他process_request和process_exception函数,也不再继续下载该请求,然后走调用process_response的流程
Request不再继续调用其他process_request函数,交由调度器重新安排下载。
IgnoreRequestprocess_exception函数会被调用,如果没有此方法,则request.errback会被调用,如果errback也没有,则此异常会被忽略,甚至连日志都没有。

process_response

在将下载结果返回给engine过程中被调用

返回值行为
Response续续调用其他中间件的process_response
Request不再继续调用其他process_request函数,交由调度器重新安排下载。
IgnoreRequest则request.errback会被调用,如果errback也没有,则此异常会被忽略,甚至连日志都没有。

process_exception

在下载过程中出现异常,或者在process_request中抛出IgnoreRequest异常的时候调用。

返回值行为
Response开始中间件链的process_response处理流程
Request不再继续调用其他process_request函数,交由调度器重新安排下载。
None继续调用其他中间件里的process_exception函数

from_crawler(cls, crawler)

如果存在该函数,则调用该函数创建中间件的实例。如果要写这个函数,一定要返回一个中间件的对象。


循环动态代理

settings

 这是一个代理IP集合

PROXIES = [
   # "http://54.243.170.209:8080",
   "http://165.225.210.96:10605"
]

# 749是有讲究的,因为系统的默认代理中间件是750,我们自定义的要运行在默认的前面,而系统会先运行数字小的中间件
# 而为了防止影响其他的中间件,所以紧挨着750就可以了
DOWNLOADER_MIDDLEWARES = {
   'qianmu.middlewares.RandomProxyMiddleware': 749,
}


middlewares

 定义一个类创建一个中间件实例

class RandomProxyMiddleware(object):

    def __init__(self, settings):
        # 初始化变量和配置
        self.proxies = settings.getlist("PROXIES")
        self.state = defaultdict(int)
        self.max_failed = 3

    @classmethod
    def from_crawler(cls, crawler):
        # 1.创建中间件对象
        if not crawler.settings.getbool("HTTPPROXY_ENABLED"):
            raise NotConfigured
        return cls(crawler.settings)

    def process_request(self, request, spider):
        # 3.为每个request对象分配一个随机的ip代理
        if self.proxies and not request.meta.get("proxy"):
            request.meta["proxy"] = random.choice(self.proxies)

    def process_response(self, request, response, spider):
        # 4.请求成功,调用process_response
        cur_proxy = request.meta.get("proxy")
        # 判断是否被对方封禁
        if response.status in (401, 403):
            print(f"{cur_proxy} got wrong code {self.state[cur_proxy]} times")
            # 给相应的IP失败次数+1
            self.state[cur_proxy] += 1
        # 当某个IP的失败次数累计到一定数量
        if self.state[cur_proxy] >= self.max_failed:
            print("got wrong http code {%s} when use %s" % (response.status, request.get("proxy")))
            # 可以认为该IP已经被对方封禁了,从代理池中将该IP删除
            self.remove_proxy(cur_proxy)
            del request.meta["proxy"]
            # 重新请求重新安排调度下载
            return request
        return response

    def process_exception(self, request, exception, spider):
        # 4.请求失败,调用process_exception
        cur_proxy = request.meta.get("proxy")

        # 如果本次请求使用了代理,并且网络请求报错,认为该IP出现问题了
        if cur_proxy and isinstance(exception, (ConnectionRefusedError, TimeoutError)):
            print(f"error occur where use proxy {exception} {cur_proxy}")
            self.remove_proxy(cur_proxy)
            del request.meta["proxy"]
            return request


    def remove_proxy(self, proxy):
        """在代理IP列表中删除指定代理"""
        if proxy in self.proxies:
            self.proxies.remove(proxy)
            print(f"remove {proxy} from proxy list")

内置中间件

在这里插入图片描述

  1. scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware

    请求robots.txt文件,并解析其中的规则。

  2. scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware

    执行带Basic-auth验证的请求

  3. scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware

    下载请求超时最大时长

  4. scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware

    设置默认的请求头信息

  5. scrapy.downloadermiddlewares.useragent.UserAgentMiddleware

    设置请求头信息里的User-Agent

  6. scrapy.downloadermiddlewares.retry.RetryMiddleware

    如果下载失败,是否重试,重试几次

  7. scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware

    实现Meta标签重定向

  8. scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware

    实现压缩内容的解析(比如gzip)

  9. scrapy.downloadermiddlewares.redirect.RedirectMiddleware

    实现30x的HTTP code的重定向

  10. scrapy.downloadermiddlewares.cookies.CookiesMiddleware

    实现对cookies的设置管理

  11. scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware

    实现IP代理

  12. scrapy.downloadermiddlewares.stats.DownloaderStats

    下载信息的统计

  13. scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware

    下载结果的缓存


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值