什么是Session?
由于Http协议具有无状态性,也就是他对事物处理没有记忆能力。当我们向web站点发送请求时,服务器并不知道用户的信息。这会带来不便,比较典型的就是淘宝的购物车,当我们向往购物车里添加商品时,由于无状态性,服务器并不能分辨不同的用户。因此,我们需要标识用户。现实中,淘宝服务器会为用户创建Session,它唯一标识了这个用户并进行跟踪。Session就是指我们打开一个网站到我们关闭浏览器的一系列的过程。Session是保存在服务器中的,它有一定的生命周期,当我们长时间
没有访问该网站,服务器会自动删掉该Session。
然而服务器端是如何识别特定的用户的呢?
什么是cookies?
我们先给出维基百科上二者的定义:
cookies指某些网站为了辨别用户身份而存储在用户本地终端上的数据(通常经过加密),目前使用最广泛的cookie标准是网景公司制定的标准上进行扩展后的产物。
事实上,在第一次创建Session时,服务器创建一个Session ID并且告知客户端在cookies中记录下来。当每次发送一个Http请求时,客户端都会发送相应的cookies信息至服务器,也即包括Session ID,这样,服务器便能够分辨用户。
cookies和Session的区别?
- 存放位置不同,Session存放在服务器中,而cookies存放在客户端
- cookie不安全, cookie存放在本地,可以进行修改欺骗
- session会保存在服务器上一定时间,会过期
- 单个cookie保存数据不超过4k。很多浏览器限制一个站点最多保存20个
使用cookies进行模拟登录
http模块提供了几种类型的CookieJar对象用于管理存储cookie,并向传出的http请求添加cookie。
该模块有四种主要的对象:
- CookieJar:管理存储cookie,向传出的http请求添加cookie,且cookie存储在内存中,CookieJar实例回收后cookie即消失。
- FileCookieJar:使用文件管理cookie。
- MozillaCookieJar:创建与mocilla浏览器cookie.txt兼容的FileCookieJar实例。
- LWPCookieJar:创建与libwww-perl标准兼容的Set-Cookie3格式的FileCookieJar实例。
这四者的派生关系为:CookieJar–>FileCookieJar–>MozillaCookieJar–>LWPCookieJar。
下面通过模拟登录人人网讲解cookieJar的使用方法。
第一步,我们先要创建一个请求管理器,这里我们使用FileCookieJar的子类MozillaCookieJar来保存cookie
urllib中的urlopen()函数不支持验证、cookie或者其他的HTTP高级功能。我们可以使用build_opener()函数创建Opener对象来支持这些功能。该函数返回一个OpenerDirector实例。
filename = 'cookie.txt' # 创建文本保存cookie
#创建cookiejar实例对象
cookie=cookiejar.MozillaCookieJar(filename)
#根据创建的cookie生成cookie的管理器
cookie_handler=request.HTTPCookieProcessor(cookie)
#请求http请求管理器
http_handler=request.HTTPHandler()
#创建https管理器
https_handler=request.HTTPSHandler()
#创建请求管理器,将三个管理器作为参数属性
#用opener替代urlopen获取请求
opener=request.build_opener(cookie_handler,http_handler,https_handler)
第二步,我们先进行初次登录并且保存cookie。
#登录URL,需要从登录form的action属性中获取
url='http://www.renren.com/PLogin.do'
#登录所需要的数据,数据为字典形式
data={
'email':'xxxxxxxxxxx',
'password':'xxxxxxxxxx'
}
#将数据解析成urlencode格式,并encode为bytes
data=parse.urlencode(data).encode('utf-8')
#req=request.Request(url,data=data)
#正常是使用request.urlopen(),这里用opener
#response=opener.open(req)
response=opener.open(url,data)
#保存cookie
cookie.save(ignore_discard=True, ignore_expires=True)
OpenerDirector.open(url, data=None[, timeout])
打开给定的url,可选地传递给定的数据。它的参数也可以是一个Request对象。该函数的参数、返回值和引发的异常与urlopen()函数一样。
其中save()函数中有两个参数:
- ignore_discard:表示即使cookies将被丢弃也将它保存下来。
- ignore_expires:表示如果该文件中cookies已经存在,则覆盖原文件。
第三步,读取cookies并且模拟登录。
url='http://www.renren.com/969036176'
res=opener.open(url)
html=res.read().decode()
with open('renren.html','w',encoding='utf-8') as f:
f.write(html)
打开获取的renren.html,页面结果为:
完整代码如下:
# -*- coding:utf-8 -*-
from urllib import request,parse
from http import cookiejar
filename = 'cookie.txt' # 创建文本保存cookie
#创建cookiejar实例对象
cookie=cookiejar.MozillaCookieJar(filename)
#根据创建的cookie生成cookie的管理器
cookie_handler=request.HTTPCookieProcessor(cookie)
#请求http请求管理器
http_handler=request.HTTPHandler()
#创建https管理器
https_handler=request.HTTPSHandler()
#创建请求管理器,将三个管理器作为参数属性
#用opener替代urlopen获取请求
opener=request.build_opener(cookie_handler,http_handler,https_handler)
def login():
'''
负责初次登录
传递用户名和密码,保存cookie
'''
#登录URL,需要从登录form的action属性中获取
url='http://www.renren.com/PLogin.do'
#登录所需要的数据,数据为字典形式
data={
'email':'xxxxxxxxxxx', #在此隐去真实账号和密码
'password':'xxxxxxxxxx'
}
#将数据解析成urlencode格式,并encode为bytes
data=parse.urlencode(data).encode('utf-8')
req=request.Request(url,data=data)
#正常是使用request.urlopen(),这里用opener
response=opener.open(req)
#保存cookie
cookie.save(ignore_discard=True, ignore_expires=True)
def getHomePage():
'''
获取登录后的页面
'''
url='http://www.renren.com/969036176'
res=opener.open(url)
print(cookie)
html=res.read().decode()
with open('renren.html','w',encoding='utf-8') as f:
f.write(html)
if __name__=='__main__':
#初次登录,获取cookie
login()
#利用cookie,模拟登录
getHomePage()