• scrapy的cookie管理


    scrapy的cookie管理

    单个请求的cookie管理

    1.设置headers

    需要把settings.py的COOKIES_ENABLED设置为false

    COOKIES_ENABLED = False
    

    示例

    def start_requests(self):
        headers = {
            "cookie":"填入cookie"
        }
        url = '请求url'
        yield Request(url, callback=self.parse, headers=headers)
    

    2.传入Request的cookies参数

    需要把settings.py的COOKIES_ENABLED设置为true

    示例

    def start_requests(self):
        url = '请求url'
        # 指定你的cookies
        cookies = {}
        yield Request(url, callback=self.parse,cookies=cookies)
    

    多个请求的cookie管理

    上面的两个方法可适用大部分情景,但如果要管理多个cookie session,每次手动添加就显得很繁杂了。这时候就用到scrapy的cookies middleware了,其使用了cookiejar来管理多个cookie。

    使用

    需要把settings.py的COOKIES_ENABLED设置为true

    for i, url in enumerate(urls):
        yield scrapy.Request("http://www.example.com", meta={'cookiejar': i},
            callback=self.parse_page)
    

    只需这一步,scrapy就会自动帮你管理该次请求与响应的cookie了。而且这可以和headers与cookies传参的方式并存,它会自动帮你加入其管理的cookie中。

    其中键必须为'cookiejar',与cookies middleware源码有关。

    该代码为每一个请求的meta中的cookiejar都赋予不同的值(实际上它并不是真正的cookiejar,只是一个内部维持请求与cookiejar的对应的key),在cookies middleware中就为每一个请求都维持管理了不同的cookie。

    上面这段代码初看可能会莫名其妙,但你看了源码就会一清二楚了。

    需要注意的是后续的请求并不会自动维持前面的cookie。 如果后续的请求也要维持前面的cookie,需要在之后的request请求中接着传递。例如:

    def parse_page(self, response):
        # do some processing
        return scrapy.Request("http://www.example.com/otherpage",
            meta={'cookiejar': response.meta['cookiejar']},
            callback=self.parse_other_page)
    

    源码简析

    本文使用源码为scrapy 2.3.0

    初始化
    from collections import defaultdict
    from scrapy.http.cookies import CookieJar
    
    class CookiesMiddleware:
        """This middleware enables working with sites that need cookies"""
    
        def __init__(self, debug=False):
            self.jars = defaultdict(CookieJar)
            self.debug = debug
    

    开始用defaultdict创建了self.jars,它就是实际上管理每个独立的cookiejar的字典

    处理请求
    def process_request(self, request, spider):
        if request.meta.get('dont_merge_cookies', False):
            return
    
        cookiejarkey = request.meta.get("cookiejar")
        jar = self.jars[cookiejarkey]
        for cookie in self._get_request_cookies(jar, request):
            jar.set_cookie_if_ok(cookie, request)
    
            # set Cookie header
            request.headers.pop('Cookie', None)
            jar.add_cookie_header(request)
            self._debug_cookie(request, spider)
    

    cookiejarkey = request.meta.get("cookiejar")就能看出为什么meta的key必须为'cookiejar'了。这也能看到,如果meta中有{'dont_merge_cookies': True}的键值对,就会跳过处理,当有单个请求不想合并cookie就可添加该键值对。

    self._get_request_cookies函数就是提取headers与request中的cookies的cookies并加入该cookiejar。这也解释了为什么cookiejar可与headers与cookies传参的方式并存。

    最后为request加入该cookiejar管理的cookie

    处理相应
    def process_response(self, request, response, spider):
        if request.meta.get('dont_merge_cookies', False):
        return response
    
        # extract cookies from Set-Cookie and drop invalid/expired cookies
        cookiejarkey = request.meta.get("cookiejar")
        jar = self.jars[cookiejarkey]
        jar.extract_cookies(response, request)
        self._debug_set_cookie(response, spider)
    
        return response
    

    与处理请求相似。

    DEBUG

    在setting.py中设置COOKIES_DEBUG = True,并且LOG_LEVEL = "DEBUG",Scrapy将记录所有在request(cookie请求头)发送的cookies及response接收到的cookies(Set-Cookie 接收头)。

    下边是启用COOKIES_DEBUG 的记录的样例:

    2011-04-06 14:35:10-0300 [scrapy] INFO: Spider opened
    2011-04-06 14:35:10-0300 [scrapy] DEBUG: Sending cookies to: <GET http://www.diningcity.com/netherlands/index.html>
            Cookie: clientlanguage_nl=en_EN
    2011-04-06 14:35:14-0300 [scrapy] DEBUG: Received cookies from: <200 http://www.diningcity.com/netherlands/index.html>
            Set-Cookie: JSESSIONID=B~FA4DC0C496C8762AE4F1A620EAB34F38; Path=/
            Set-Cookie: ip_isocode=US
            Set-Cookie: clientlanguage_nl=en_EN; Expires=Thu, 07-Apr-2011 21:21:34 GMT; Path=/
    2011-04-06 14:49:50-0300 [scrapy] DEBUG: Crawled (200) <GET http://www.diningcity.com/netherlands/index.html> (referer: None)
    

    如有纰漏,欢迎斧正

    参考文献

    scrapy设置cookie的三种方式

    Scrapy文档

  • 相关阅读:
    为 Jenkins 配置 .NET 持续集成环境
    树莓派连接GPS模块
    杂记
    大型网站架构系列:电商网站架构案例
    我的心博客。
    555555555555111
    powershell 环境变量只有当前会话起作用问题
    powershell 下独立silent 安装 浏览器问题
    python编码格式
    scss教程推荐
  • 原文地址:https://www.cnblogs.com/lymmurrain/p/15790869.html
Copyright © 2020-2023  润新知