Cookie

Cookie 是指某些网站服务器为了辨别用户身份和进行Session跟踪,而储存在用户浏览器上的文本文件数据(通常都是经过加密的),Cookie可以保持登录信息到用户下次与服务器的会话。

 

Cookie原理

HTTP是无状态的面向连接的协议, 为了保持连接状态, 引入了Cookie机制 Cookie是http消息头中的一种属性,包括:

 

Cookie名字(Name)

Cookie的值(Value)

Cookie的过期时间(Expires/Max-Age)

Cookie作用路径(Path)

Cookie所在域名(Domain),

使用Cookie进行安全连接(Secure)指的是该cookies是否仅能被安全协议传输,默认为false。

sameSite是否是同一个站点

 

前两个参数是Cookie应用的必要条件,另外,还包括Cookie大小(Size,不同浏览器对Cookie个数及大小限制是有差异的)。

那么,我们怎样利用Cookies保持状态呢?当客户端第一次请求服务器时,服务器会返回一个请求头中带有Set-Cookie字段的响应给客户端,用来标记是哪一个用户,客户端浏览器会把Cookies保存起来。当浏览器下一次再请求该网站时,浏览器会把此Cookies放到请求头一起提交给服务器,Cookies携带了会话ID信息,服务器检查该Cookies即可找到对应的会话是什么,然后再判断会话来以此来辨认用户状态。

 

在成功登录某个网站时,服务器会告诉客户端设置哪些Cookies信息,在后续访问页面时客户端会把Cookies发送给服务器,服务器再找到对应的会话加以判断。如果会话中的某些设置登录状态的变量是有效的,那就证明用户处于登录状态,此时返回登录之后才可以查看的网页内容,浏览器再进行解析便可以看到了。

 

反之,如果传给服务器的Cookies是无效的,或者会话已经过期了,我们将不能继续访问页面,此时可能会收到错误的响应或者跳转到登录页面重新登录。

 

所以,Cookies和会话需要配合,一个处于客户端,一个处于服务端,二者共同协作,就实现了登录会话控制。

 

Cookie由变量名和值组成,根据 Netscape公司的规定,Cookie格式如下:

 

Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE

 

下面我们来模拟一下人人网的登录

1.首先我们在网页是那个登录(这里我选择的是火狐浏览器

找到入下图所示位置:

获取到一个有登录信息的Cookie模拟登陆

# -*- coding:utf-8 -*-

import urllib.request

 

url = 'http://www.renren.com/'

 

#根据刚才的登录信息来构建一个已经登录过的用户的headers信息

 

headers = {

    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',

    'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',

    'User-Agent':' Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:59.0) Gecko/20100101 Firefox/59.0',

    'Upgrade-Insecure-Requests':'1',

    'Connection':'keep-alive',

    'Host':'www.renren.com',

    'Cookie':'anonymid=jgoj4xlw-3izsk4; depovince=BJ; jebecookies=62d94404-de1f-450a-919b-a2d9f4c8b811|||||; _r01_=1; JSESSIONID=abchsGLNgne0L8_wz2Emw; ick_login=cf54f2dc-8b0b-417a-96b2-32d4051f7236; jebe_key=02cb19ad-2966-4641-8828-217160ca67a0%7Cba6f6d6ec917200a4e17a85dbfe33a4a%7C1525230975024%7C1%7C1525230982574; t=87a502d75601f8e8c0c6e0f79c7c07c14; societyguester=87a502d75601f8e8c0c6e0f79c7c07c14; id=965706174; xnsid=e1264d85; ver=7.0; loginfrom=null; wp_fold=0',

}

 

# 2. 通过headers里的报头信息(主要是Cookie信息),构建Request对象

request = urllib.request.Request(url, headers=headers)

 

# 3. 直接访问renren主页,服务器会根据headers报头信息(主要是Cookie信息)

#,判断这是一个已经登录的用户,并返回相应的页面

response = urllib.request.urlopen(request)

 

# 4. 打印响应内容

print(type(response.read()))

 

with open('cookie.html','wb+') as file:

    print(response.read())

    file.write(response.read())

 

运行程序将文件写入本地:

获取到的html文件格式如下

 

那么我们通过上面的代码可以看到其实是实现了获取Cookie,通过Cookie来请求网页数据的

但是我们有没有方便一点的做法呢?

 

 

http.cookiejar库 和 HTTPCookieProcessor处理器

 

在Python处理Cookie,python3之后是通过http.cookiejar模块和 urllib模块的HTTPCookieProcessor处理器类一起使用。

 

http.cookiejar模块:主要作用是提供用于存储cookie的对象

HTTPCookieProcessor处理器:主要作用是处理这些cookie对象,并构建handler对象。

 

http.cookiejar 库

该模块主要的对象有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。

  • CookieJar:管理HTTP cookie值、存储HTTP请求生成的cookie、向传出的HTTP请求添加cookie的对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失。

  • FileCookieJar (filename,delayload=None,policy=None):从CookieJar派生而来,用来创建FileCookieJar实例,检索cookie信息并将cookie存储到文件中。filename是存储cookie的文件名。delayload为True时支持延迟访问访问文件,即只有在需要时才读取文件或在文件中存储数据。

  • MozillaCookieJar (filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与Mozilla浏览器 cookies.txt兼容的FileCookieJar实例。

  • LWPCookieJar (filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与libwww-perl标准的 Set-Cookie3 文件格式兼容的FileCookieJar实例。

 

其实大多数情况下,我们只用CookieJar(),如果需要和本地文件交互,就用 MozillaCookjar() 或 LWPCookieJar()

 

案例(一):以百度为例

目的:获取Cookie,并保存到CookieJar()对象中

 

案例2: MozillaCookjar()

访问网站或者cookie,并且把获得的cookie保存在创建的cookie文件中

 

案例3:MozillaCookjar()

从文件中获取cookies,作为请求的一部分去访问

 

 

案例4: CookieJar()

利用cookiejar和post登录人人网

 

# -*- coding:utf-8 -*-

import urllib.request

import http.cookiejar as cookiejar

from urllib import parse

 

#1.构造一个CookieJar对象实例来保存cookie

cookie = cookiejar.CookieJar()

 

# 2.使用HTTPCookieProcessor()创建cookie处理器对象,

# 参数为CookieJar()对象

cookie_handler = urllib.request.HTTPCookieProcessor(cookie)

 

#3.通过build_opener()来构建opener

opener = urllib.request.build_opener(cookie_handler)

 

#4.addheaders接受一个列表,里面每一个元素都是一个headers信息的元组

#opener将会附带header信息

opener.addheaders = [

    ('User-Agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:59.0) Gecko/20100101 Firefox/59.0'),

]

 

#5.需要登录账号和密码

data = {

    'email':'18518753265',

    'password':'ljh1990123',

}

 

# # 6. 通过urlencode()转码

postdata = parse.urlencode(data).encode('utf-8')

 

# # 7. 构建Request请求对象,包含需要发送的用户名和密码

request = urllib.request.Request("http://www.renren.com/PLogin.do", data = postdata)

 

# # 8. 通过opener发送这个请求,并获取登录后的Cookie值,

opener.open(request)

 

# # 9. opener包含用户登录后的Cookie值,可以直接访问那些登录后才可以访问的页面

response = opener.open("http://www.renren.com/965722397/profile")

 

#这里为了测试不添加cookie时访问改界面的效果

#headers = {

#    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:59.0) Gecko/20100101 #Firefox/59.0',

#}

# request = urllib.request.Request('http://www.renren.com/965722397/profile',headers=headers)

# response = urllib.request.urlopen(request)

 

# 10. 打印响应内容

#打印结果查看是否访问成功

print(response.code)

html = response.read()

# print(html)

 

with open('renren.html','wb') as f:

    f.write(html)

 

访问个人信息成功时返回的html部分界面截图如下说明成功:

模拟登录要注意几点:

  1. 登录一般都会先有一个HTTP GET,用于拉取一些信息及获得Cookie,然后再HTTP POST登录。

  2. HTTP POST登录的链接有可能是动态的,从GET返回的信息中获取。

  3. password 有些是明文发送,有些是加密后发送。有些网站甚至采用动态加密的,同时包括了很多其他数据的加密信息,只能通过查看JS源码获得加密算法,再去破解加密,非常困难。

  4. 大多数网站的登录整体流程是类似的,可能有些细节不一样,所以不能保证其他网站登录成功.

 

这个测试案例中,为了想让大家快速理解知识点,我们使用的人人网登录接口是人人网改版前的隐藏接口(嘘....),登录比较方便。

 

当然,我们也可以直接发送账号密码到登录界面模拟登录,但是当网页采用JavaScript动态技术以后,想封锁基于 HttpClient 的模拟登录就太容易了,甚至可以根据你的鼠标活动的特征准确地判断出是不是真人在操作。

 

所以,想做通用的模拟登录还得选别的技术,比如用内置浏览器引擎的爬虫(关键词:Selenium ,PhantomJS),这个我们将在以后会学习到。

 

另外:我们这里所讲的都是基于Python3 之后的,之前有捎带


 

由于涉及一些专业名词知识,部分内容参考来源如下。

会话百度百科:https://baike.baidu.com/item/session/479100

Cookies百度百科:https://baike.baidu.com/item/cookie/1119

HTTP Cookie维基百科:https://en.wikipedia.org/wiki/HTTP_cookie

会话和几种状态保持方案理解:http://www.mamicode.com/info-detail-46545.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值