需要把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)
需要把settings.py的COOKIES_ENABLED设置为true
示例
def start_requests(self): url = '请求url' # 指定你的cookies cookies = {} yield Request(url, callback=self.parse,cookies=cookies)
上面的两个方法可适用大部分情景,但如果要管理多个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
与处理请求相似。
在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文档