zoukankan      html  css  js  c++  java
  • 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文档

  • 相关阅读:
    [ jquery 选择器 :hidden ] 此方法选取匹配所有不可见元素,或者type为hidden的元素
    剑指 Offer 03. 数组中重复的数字 哈希
    LeetCode 1736. 替换隐藏数字得到的最晚时间 贪心
    Leetcode 1552. 两球之间的磁力 二分
    Leetcode 88. 合并两个有序数组 双指针
    LeetCode 1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?
    LeetCode 1743. 相邻元素对还原数组 哈希
    LeetCode 1745. 回文串分割 IV dp
    剑指 Offer 47. 礼物的最大价值 dp
    剑指 Offer 33. 二叉搜索树的后序遍历序列 树的遍历
  • 原文地址:https://www.cnblogs.com/lymmurrain/p/15790869.html
Copyright © 2011-2022 走看看