Scrapy源码注解--CookiesMiddleware
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的获取/传递/本地保存"中的疑惑.
Scrapy源码注解--CookiesMiddleware的更多相关文章
- Scrapy源码学习(一)
用Scrapy已经有一段时间了,觉得该是看一下源码的时候了.最开始用的时候还是0.16的版本,现在稳定版已经到了0.18.结合使用Scrapy的过程,先从Scrapy的命令行看起. 一.准备 下载源代 ...
- DispatcherServlet源码注解分析
DispatcherServlet的介绍与工作流程 DispatcherServlet是SpringMVC的前端分发控制器,用于处理客户端请求,然后交给对应的handler进行处理,返回对应的模型和视 ...
- scrapy源码分析(转)
记录一下两个讲解scrapy源码的博客: 1.http://kaito-kidd.com/2016/11/21/scrapy-code-analyze-component-initialization ...
- 通过更改scrapy源码进行spider分发实现一个综合爬虫
最近我正写一个项目,项目的需求如下一,要爬取大约100种几百个网页的类容,并且这些网页的爬取频率不一样,有些一天爬取一次,有些一周爬取一次,二,网页爬取内容有变化,也就是说要爬取的内容会根据需求进行改 ...
- fastclick 源码注解及一些基础知识点
在移动端,网页上的点击穿透问题导致了非常糟糕的用户体验.那么该如何解决这个问题呢? 问题产生的原因 移动端浏览器的点击事件存在300ms的延迟执行,这个延迟是由于移动端需要通过在这个时间段用户是否两次 ...
- Twisted使用和scrapy源码剖析
1.Twisted是用Python实现的基于事件驱动的网络引擎框架. 事件驱动编程是一种编程范式,这里程序的执行流由外部事件来决定.它的特点是包含一个事件循环,当外部事件发生时使用回调机制来触发相应的 ...
- zepto源码注解
/* Zepto v1.0-1-ga3cab6c - polyfill zepto detect event ajax form fx - zeptojs.com/license */ ;(funct ...
- linux内核源码注解
轻松学习Linux操作系统内核源码的方法 针对好多Linux 爱好者对内核很有兴趣却无从下口,本文旨在介绍一种解读linux内核源码的入门方法,而不是解说linux复杂的内核机制:一.核心源程序的文件 ...
- Spring 源码注解
一.@Retention可以用来修饰注解,是注解的注解,称为元注解. Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolic ...
随机推荐
- Intelj IDEA的pom.xml显示错误can not reconnect
从GitHub上边down下来的开源项目,报错莫名其妙,后来发现是跟本地hosts文件有关系 hosts文件加上 127.0.0.1 localhost 然后pom文件reload一下就
- Android 6.0以上 需要运行时申请的权限
转载:http://www.cnblogs.com/tangs/articles/6377347.html 自从Android6.0发布以来,在权限上做出了很大的变动,不再是之前的只要在manifes ...
- java基础-day2
第02天 java基础知识 今日内容介绍 u Eclipse的安装.配置及使用 u 运算符 u 键盘录入 第1章 Eclipse开发工具 1.1 Eclipse概述和安装 Eclipse是一个I ...
- POJ3026 Borg Maze 2017-04-21 16:02 50人阅读 评论(0) 收藏
Borg Maze Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14165 Accepted: 4619 Descri ...
- Codeforces 632D Longest Subsequence 2016-09-28 21:29 37人阅读 评论(0) 收藏
D. Longest Subsequence time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- jsPlumb学习笔记
这就是一个给元素画连接线的工具. <!DOCTYPE html> <html> <head> <title>jsPlumb</title> ...
- delphi TStringList 用法详解
转自: http://blog.163.com/you888@188/blog/static/67239619201472365642633/ delphi TStringList 用法详解 2014 ...
- Git安全配置
今天收到了阿里云异地登录的短信报警,登录阿里云后台发现,有人从深圳登录了我的服务器(本人在北京),查看详细信息一共登录了5次,前两次是使用的git用户进行登录,后两次已经变成了root用户,怀疑是 ...
- 在centos docker中安装nvidia驱动
因为计算需要用到GPU加速, 今天尝试在centos 机器的Docker里安装了GTX980驱动, 记录一下详细安装过程. 首先安装Docker和镜像: sudo yum install docker ...
- EF添加Msysql实体异常:表“TableDetails”中列“IsPrimaryKey”的值为 DBNull。 ---> System.InvalidCastException: 指定的转换无效。
尝试一下以下步骤: 1.关闭VS项目, 以管理员权限来打开: 1.执行语句 set global optimizer_switch='derived_merge=OFF'; set optimizer ...