scrapy cookies:將cookies保存到文件以及從文件加載cookies


我在使用scrapy模擬登錄新浪微博時,想將登錄成功后的cookies保存到本地,下次加載它實現直接登錄,省去中間一系列的請求和POST等。關於如何從本次請求中獲取並在下次請求中附帶上cookies的方法,官方文檔已經有很好的說明,網上也有很多相關的資料,但是將cookies存儲到文件和從文件加載cookies卻未找到相關的說明,只好自己折騰了,經過一番嘗試,總算是實現了該功能,方法記錄如下。

簡單分析scrapy的cookies

查看scrapy與cookies有關的源碼,在http/cookies.py文件中,下面是部分代碼:

import time
from cookielib import CookieJar as _CookieJar, DefaultCookiePolicy, IPV4_RE
from scrapy.utils.httpobj import urlparse_cached

class CookieJar(object):
    def __init__(self, policy=None, check_expired_frequency=10000):
        self.policy = policy or DefaultCookiePolicy()
        self.jar = _CookieJar(self.policy)
        self.jar._cookies_lock = _DummyLock()
        self.check_expired_frequency = check_expired_frequency
        self.processed = 0
    
    def extract_cookies(self, response, request):
        wreq = WrappedRequest(request)
        wrsp = WrappedResponse(response)
        return self.jar.extract_cookies(wrsp, wreq)
    
    @property
    def _cookies(self):
        return self.jar._cookies

    def set_cookie(self, cookie):
        self.jar.set_cookie(cookie)

可以看出scrapy的CookieJar類基本上是通過cookielib的CookieJar類來實現的相應功能。

獲取cookies

metacookie_jar設置為CookieJar對象,通過response.meta['cookie_jar']即可獲得cookies的內容。

from scrapy.http.cookies import CookieJar

cookie_jar = CookieJar()
return [scrapy.FormRequest(url="http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)",
                           formdata=self.login_data,
                           meta = {'dont_merge_cookies': True, 'cookiejar': cookie_jar},#首次請求
                           callback=self.after_post)]

......
#之后的每次請求通過傳遞這個CookieJar對象
yield scrapy.Request(login_url, meta = {'dont_merge_cookies': True, 'cookiejar' : response.meta['cookiejar']}, callback=self.verify_login)

......
#登錄成功后,得到要保存的cookies,為CookieJar對象
cookie_jar = response.meta['cookiejar']
cookie_jar.extract_cookies(response, response.request)

將cookies存儲到文件

可以通過CookieJar._cookies方法將cookies轉換為字典類型進行存儲,也可以通過遍歷的方式將各條cookies分別存儲,為了后續解析的簡單,我選擇了遍歷的方式:

with open(self.cookie_file, 'wb+') as f:
    for cookie in cookie_jar:
        f.write(str(cookie) + '\n')

這種方式相比直接存儲為字典格式的方式而言,遍歷后自動忽略了一部分cookies,數量相比后者有明顯減少,但分析后發現,關於最后一次請求也就是登錄成功時的請求的cookies都被保存了下來,沒有被忽略,如果不放心,完全可以直接解析完整的字典類型的cookies。保存下來的cookies格式如:

<Cookie SRF=1456586813 for .passport.weibo.com/>
......
<Cookie SSOLoginState=1456586813 for .weibo.com/>

從文件加載cookies

通過FireFox分析微博登錄成功時的請求返回的cookies以及這篇博客可知,用於登錄的cookies的domain都是.weibo.com,那么可以通過正則表達式從文件中提取相關的cookies:

with open(self.cookie_file) as f:
    cookiejar = f.read()
    
p = re.compile('\<Cookie (.*?) for .weibo.com\/\>')
cookies = re.findall(p, cookiejar)
cookies = (cookie.split('=') for cookie in cookies)
cookie_jar = dict(cookies)

這里之所以將讀取的cookies轉換為字典類型,是因為若要在scrapy的請求中手動添加cookies,需要使用scrapy.Request方法中的cookies參數。將從文件中加載的字典類型的cookie_jar賦值給cookies參數,可以實現直接登錄微博:

yield scrapy.Request(url='http://weibo.com', cookies=cookie_jar, callback=self.logined)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM