环境: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.Request
的cookies
参数中,cookie在后续的请求中会自行流转.
scrapy.Request(url, callback=self.xxx, cookies=cookies)
关于request meta key中cookiejar的作用请参看Scrapy源码注解–CookiesMiddleware–2017.12.18