Scrapy框架--cookie的获取/传递/本地保存

环境:Python3.6 + Scrapy1.4
我要实现的东西:1. 完成模拟登陆
        2. 登陆成功后提取出cookie,然后保存到本地cookie.txt文件中
        3. 再次使用时从本地的cookie.txt中读取cookie,省略模拟登陆.


看了一些关于Scrapy操作cookie的博客,写的大同小异(都不好使...).我总结一下我尝试出来的关于cookie的提取和传递的操作,亲测可用

Cookie的传递和提取

from scrapy.http.cookies import CookieJar    # 该模块继承自内置的http.cookiejar,操作类似

# 实例化一个cookiejar对象
cookie_jar = CookieJar()

# 首先是cookie的提取
class MySpider(scrapy.Spider):
    ....
    ....
    # 模拟登陆,之后调用一个检查是否登录成功的函数
    def login(self, response):
        ....
        return [scrapy.FormRequest(
            url=login_url,
            formdata = {'username':xxx, 'password':xxx},
            callback = self.check_login
        )]

def check_login(self, response):
    if 登录成功:
        # 到这里我们的登录状态已经写入到response header中的'Set-Cookies'中了,
        # 使用extract_cookies方法可以提取response中的cookie
        cookiejar.extract_cookies(response, response.request)
        # cookiejar是类字典类型的,将它写入到文件中
        with open('cookies.txt', 'w') as f:
            for cookie in cookie_jar:
                f.write(str(cookie) + '\n')

# 有些情况可能在发起登录之前会有一些请求,会陆续的产生一些cookie,可以在第一次请求的时候将cookiejar写入到request的meta中进行传递
scrapy.Request(url, callback=self.xxx, meta={'cookiejar': cookiejar})
# 之后每次需要传递这个cookiejar对象可以从response.meta中拿到
scrapy.Request(url, callback=self.xxx, meta={'cookiejar': response.meta['cookiejar']})

看了不少博文中只是写将cookie添加到meta中,这样就可以在请求的过程中获取到cookie.我这样尝试过,cookiejar在多个请求-响应中流转后依然是空的,所以只能在需要的时候使用cookiejar.extract_cookies方法进行手动提取.
若哪位大神知道meta中的cookiejar自行获取cookie的方法,请评论指点,谢谢!

从本地文件中读取Cookie

     with open('cookies.txt', 'r') as f:
         cookiejar = f.read()
         p = re.compile(r'<Cookie (.*?) for .*?>')
         cookies = re.findall(p, cookiejar)
         cookies = (cookie.split('=', 1) for cookie in cookies)
         cookies = dict(cookies)

之后可以在第一次发起请求(start_request)时将cookie手动添加到scrapy.Requestcookies参数中,cookie在后续的请求中会自行流转.

scrapy.Request(url, callback=self.xxx, cookies=cookies)



关于request meta key中cookiejar的作用请参看Scrapy源码注解--CookiesMiddleware--2017.12.18

推荐阅读更多精彩内容