Scrapy源碼註解--CookiesMiddleware

来源:http://www.cnblogs.com/thunderLL/archive/2017/12/18/8060279.html
-Advertisement-
Play Games

CookiesMiddleware預設情況下實現了cookie在請求 響應之間的流轉和填充. 又可以通過 來實現單Spider多cookie. 通過讀源碼也解答了上一篇博文" "Scrapy框架 cookie的獲取/傳遞/本地保存" "中的疑惑. ...


class CookiesMiddleware(object):
    """
    中間件在Scrapy啟動時實例化.其中jars屬性是一個預設值為CookieJar對象的dict.
    該中間件追蹤web server發送的cookie,保存在jars中,併在之後的request中發送回去,
    類似瀏覽器的行為.

    CookiesMiddleware還用於實現單Spider多cookie.通過在Request meta中添加cookiejar來支持單
    spider追蹤多cookie session.預設情況下其使用一個cookie jar(session),不過您可以傳遞一個
    標示符來使用多個。
    例如:
    for i, url in enumerate(urls):
        yield scrapy.Request("http://www.example.com", meta={'cookiejar': i},callback=self.parse_page)
    註意:meta中的cookiejar僅存儲了cookiejar的標識,真是的cookiejar存儲在CookiesMiddleware實
    例的jars屬性中
    """
    def __init__(self, debug=False):
        self.jars = defaultdict(CookieJar)
        self.debug = debug

    @classmethod
    def from_crawler(cls, crawler):
        # COOKIES_ENABLED預設值為True,是否啟用CookiesMiddleware
        # COOKIES_DEBUG預設值為False,如果啟用,Scrapy將記錄所有在request(Cookie 請求頭)發
        # 送的cookies及response接收到的cookies(Set-Cookie 接收頭)。
        if not crawler.settings.getbool('COOKIES_ENABLED'):
            raise NotConfigured
        return cls(crawler.settings.getbool('COOKIES_DEBUG'))

    def process_request(self, request, spider):
        if request.meta.get('dont_merge_cookies', False):
            return
        # 如果在request meta中使用了cookiejar, cookiejarkey為對應的標識.
        # 否則cookiejarkey為None
        cookiejarkey = request.meta.get("cookiejar")
        # 第一次執行jars會為每個key產生一個預設值cookiejar對象.預設為{None: cookiejar}
        jar = self.jars[cookiejarkey]    
       # 見下麵_get_request_cookies()方法
        cookies = self._get_request_cookies(jar, request)
        for cookie in cookies:
            jar.set_cookie_if_ok(cookie, request)
        # set Cookie header
        request.headers.pop('Cookie', None)
        # 將cookie加入到request的headers中
        jar.add_cookie_header(request)
        self._debug_cookie(request, spider)

    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]
       # 在請求允許的情況下(?),從response中提取cookie併入當前的cookiejar
        jar.extract_cookies(response, request)
        self._debug_set_cookie(response, spider)

        return response
    ...
    ...

    def _format_cookie(self, cookie):
        # 對以字典或字典的列表的形式傳入的cookie進行格式化
        cookie_str = '%s=%s' % (cookie['name'], cookie['value'])

        if cookie.get('path', None):
            cookie_str += '; Path=%s' % cookie['path']
        if cookie.get('domain', None):
            cookie_str += '; Domain=%s' % cookie['domain']

        return cookie_str

    def _get_request_cookies(self, jar, request):
        # 將request中cookies參數添加的cookie合併到當前的cookiejar中
        if isinstance(request.cookies, dict):
            cookie_list = [{'name': k, 'value': v} for k, v in \
                    six.iteritems(request.cookies)]
        else:
            cookie_list = request.cookies

        cookies = [self._format_cookie(x) for x in cookie_list]
        headers = {'Set-Cookie': cookies}
        # 使用剛纔獲取的cookie構造一個響應對象
        response = Response(request.url, headers=headers)
        # cookiejar.make_cookies方法從response中提取cookie放入當前cookiejar中.
        return jar.make_cookies(response, request)

CookiesMiddleware預設情況下實現了cookie在請求-響應之間的流轉和填充.
又可以通過scrapy.Request(url, meta={'cookiejar': n})來實現單Spider多cookie.
通過讀源碼也解答了上一篇博文"Scrapy框架--cookie的獲取/傳遞/本地保存"中的疑惑.


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • background: -webkit-linear-gradient(top,#ffffff,#f5f5f5); background: -moz-linear-gradient(top,#ffffff,#f5f5f5); background: -webkit-gradient(linear, ... ...
  • --> ...
  • 單列模式是設計模式中使用最為普遍的模式之一,它是一種對象創建模式,用於產生一個對象的實例,它可以確保一個類只產生一個實例。 單例模式的兩大好處: 1.對於頻繁使用的對象,可以省略創建對象花費的時間。 2.因為new減少,所以對記憶體使用頻率降低,可以減少gc壓力,縮短jc停頓時間。 單例類實現方式:使 ...
  • Nginx 反向代理 負載均衡 虛擬主機配置 通過本章你將學會利用Nginx配置多台虛擬主機,清楚代理伺服器的作用,區分正向代理和反向代理的區別,搭建使用Nginx反向搭理和負載均衡,瞭解Nginx常用配置的說明。即學即用,你還在等什麼?一睹為快先瞭解Nginx的三大功能 Nginx 可以作為一臺h ...
  • 什麼是消息隊列 消息是指在兩個獨立的系統間傳遞的數據,這兩個系統可以是兩台電腦,也可以是兩個進程。 消息可以非常簡單,可以是簡單的字元串,也可以是保存了數據持久化的各種類型的文檔集合。 隊列是在消息的傳輸過程中的通道,是保存消息的容器,根據不同的情形,可以有先進先出,優先順序隊列等區別 。 為什麼使 ...
  • urllib庫對照速查表 Python2.X Python3.X urllib urllib.request, urllib.error, urllib.parse urllib2 urllib.request, urllib.error urllib2.urlopen urllib.request ...
  • C++中rand()函數可以用來產生隨機數,但是是屬於偽隨機數。 rand()函數用法: 在使用rand()函數的時候,首先需要包含頭文件#include<stdlib.h>,用法是int rand(void),產生的隨機數範圍是0~65536,類型為unsigned int,不能超過範圍。rand ...
  • [ERROR] COMPILATION ERROR : [INFO] [ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?[INFO] 1 er ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...