scrapy 中间件 middlewares.py

目录

 

def process_spider_input(self, response, spider):

def process_spider_output(self, response, result, spider):

def process_spider_exception(self, response, exception, spider):

def process_start_requests(self, start_requests, spider):


def spider_opened():

程序运行记录,参数 spider 代表项目 spider 文件夹的 spider 程序

 

 

def from_crawler(cls, crawler):

访问 setting 和 signals 的入口函数,重写这个方法需要返回实例对象如果返回对象里带有参数,可在 __inti__ 你使用

# 重写__init__
# 参数 MySetting 来自 from_crawler 的返回参数
def __init__(self,MySetting=None)
    pass
# 重写 from_crawler
@classmethod
def from_crawler(cls,crawler):
    # 从配置文件读取 MySetting 内容
    MySetting = crawler.settings.get('MySetting')
    # 返回实例对象,并设置参数 MySetting
    return cls(MySetting)

 

 

 

def process_spider_input(self, response, spider):

当 response 通过 spider 中间件时,该方法被调用,处理该 response,它应该返回 None 或者抛出一个异常

  • 如果返回 None,则 scrapy 会继续处理该 response,调用所有其他中间件直到 spider 处理该 response
  • 如果抛出一个异常,则 scrapy 不会调用任何其他中间件的 process_spider_input() 方法,并调用 request 的 errback,

的输出会以另一个方向被重新输入中间件链中,使用 process_spider_output() 方法来处理,当其抛出异常时则调用                         process_spider_exception()

 

 

def process_spider_output(self, response, result, spider):

当 scrapy 处理 response 返回 result 时,该方法被调用,它必须返回包含 request 或 Item 对象的可迭代对象

  • result 参数:包含 request 或 Item 对象的可迭代对象,spider 返回的 result

 

 

def process_spider_exception(self, response, exception, spider):

当 spider 或 其他 spider 的中间件 的 process_spider_input() 抛出异常时,被调用,它要么返回 None,要么返回一个包含                 response 或 Item 对象的可迭代对象

  • 如果返回 None,则 scrapy 继续处理该异常,调用中间键链中的其它中间键的 process_spider_exception() 方法,直到所有中间间都被调用,该异常到达引擎(异常将被记录并忽略)
  • 如果返回一个可迭代对象,则中间件链的 process_spider_output() 方法将被调用。其它的 process_spider_exception() 不会被调用
  • exception 参数:被抛出的异常

 

 

def process_start_requests(self, start_requests, spider):

以 spider 启动的 request 为参数被调用,执行的过程类似于 process_spider_output(),只不过没有关联的 response,并且必须返回的 request(不是Item)

其接受一个可迭代对象,返回另一个包含 request 对象的可迭代对象

 

 

内置下载中间件 CookiesMiddleware

几个核心方法

from_crawler 

从配置文件中读取 COOKIES_ENABLED,决定是否启用该中间件,如果启用,调用构造器创建对象,否则抛出 NotConfigured 异常,scrapy 件忽略该中间件

__init__

为避免爬虫想同时登陆 cookie 冲突,会让每一个账号发送的 http 请求使用不同的 cookiejar如:

Request(url1,meta={'cookiejar':'account1'})

Request(url2,meta={'cookiejar':'account2'})

proceess_request

处理每一个待发送的 Request 对象,尝试从 request.meta['cookiejar'] 获取用户指定使用的 cookiejar,如果用户未指定,使用默认的 cookiejar(self.jars[None])。调用 self._get_request_cookies 方法发送请求 request 应携带的 cookie 信息,填写到 http 请求头部

process_reponse

处理每一个 Resonse 对象,依然通过 request.meta['cookiejar'] 获取 cookiejar 对象,调用 extract_cookies 方法将http 响应头部中的 cookiejar 信息保存到 cookiejar 对象中

 

使用浏览器 cookie 的中间件

from scrapy.downloadermiddlewares.cookies import CookiesMiddleware
import browsercookie


class BrowserCookiesMiddleware(CookiesMiddleware):
    """
    使用浏览器中的 cookie
    """
    def __init__(self,debug=False):
        super().__init__(debug)
        self.load_browser_cookies()
        
    def load_browser_cookies(self):
        #加载 Chrome 浏览器中的 cookie
        jar = self.jars['chrome']
        chrome_cookiejar = browsercookie.chrome()
        for cookie in chrome_cookiejar:
            jar.set_cookie(cookie)
  • 继承 cookiesmiddleware 并实现构造器方法,在构造器方法中先调用基类的构造器方法,然后调用 self.load_browser_cookies 方法加载浏览器 cookie
  • 在 load_browser_cookies 方法中,使用 self.jars['chrome'] 和 self.jars['firefox'] 从默认字典中获得两个 cookiejar 对象,然后调用 browsercookie 的 chrome 和 firefox 方法,分别获取两个浏览器中的 cookie,将他们填入各自的 cookiejar 对象中

 

 

从 json 文件中获取随机代理中间件

from scrapy.downloadermiddlewares.httpproxy import HttpProxyMiddleware
from collections import defaultdict
import json
import  random


class RandomHttpProxyMiddleware(HttpProxyMiddleware):
    """
    随机代理中间件
    """
    def __init__(self,auth_encoding='latin-1',proxy_list_file=None):
        if not proxy_list_file:
            raise NotConfigured

        self.auth_encoding = auth_encoding
        # 分别用两个列表维护 HTTP 和 HTTPS 的代理,
        self.proxies = defaultdict(list)

        # 从 json 文件中读取代理服务器信息,填入 self.proxies
        with open(proxy_list_file) as f:
            proxy_list = json.load(f)
            for proxy in proxy_list:
                scheme = proxy['proxy_scheme']
                url = proxy['proxy']
                self.proxies[scheme].append(self._get_proxy(url,scheme))

    @classmethod
    def from_crawler(cls, crawler):
        # 从配置文件中读取用户验证信息的编码
        auth_encoding = crawler.settings.get('HTTPPROXY_AUTH_ENCODING','latain-1')

        # 从配置文件中读取代理服务器列表文件(json)的路径
        proxy_list_file = crawler.settings.get('HTTPPROXY_PROXY_LIST_FILE')

        return cls(auth_encoding,proxy_list_file)

    def _set_proxy(self, request, scheme):
        # 随机选取一个代理
        creds,proxy = random.choice(self.proxies[scheme])
        request.meta['proxy'] = proxy
        if creds:
            request.headers['Proxy-Authorization'] = b'Basic' + creds

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值