什么是cookie?
在爬虫的使用中,如果涉及登录等操作时,经常会使用到cookie。简单的来说,我们访问每一个互联网页面,都是通过HTTP协议进行的,而HTTP协议是一个无状态协议,所谓的无状态协议就是无法维持会话之间的状态。比如,仅使用HTTP协议的话,我们登录一个网站的时候,假如登录成功了,但是当我们访问该网站的其他网页时,该登录状态会消失,此时还需要再次登录,只要涉及网页的更新,就需要反复地登录,这是非常麻烦的。所以此时,我们需要将对应的会话信息,比如登录成功等信息通过一些方式保存下来,比较常用的方式有两种:通过Cookie保存会话信息或通过Session保存会话信息。
cookie的内容主要包括:名字,值,过期时间,路径和域。路径与域一起构成cookie的作用范围。若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式。
- Name 和 Value 属性由程序设定,默认值都是空引用。
- Domain属性的默认值为当前URL的域名部分,不管发出这个cookie的页面在哪个目录下的。
- Path属性的默认值是根目录,即 ”/” ,不管发出这个cookie的页面在哪个目录下的。可以由程序设置为一定的路径来进一步限制此cookie的作用范围。
- Expires 属性,这个属性设置此Cookie 的过期日期和时间。
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。
cookie 和session 的区别:
- cookie数据存放在客户的浏览器上,session数据放在服务器上。
- cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie。
- 存储数据量方面:session 能够存储任意的 java 对象,cookie 只能存储 String 类型的对象。
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
使用python处理Cookie,在python3可以使用Cookiejar库进行处理,而在python2中则使用Cookielib库进行处理。在此之前呢,我们必须先介绍一个opener的概念。
opener
在前面,我们都是使用的默认的opener,也就是urlopen。它是一个特殊的opener,可以理解成opener的一个特殊实例,传入的参数仅仅是url,data,timeout。如果我们需要用到Cookie,只用这个opener是不能达到目的的,所以我们需要创建更一般的opener来实现对Cookie的设置。
代码实战
未使用cookie登录
# -*- coding:UTF-8 -*-
import urllib.request
import urllib.parse
url = "http://bbs.chinaunix.net/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LfgTz"
postdata = urllib.parse.urlencode({
"username": "weisuen",
"password": "aA123456"
}).encode('utf-8') # 使用urlencode编码处理后,再设置为utf-8编码
req = urllib.request.Request(url, postdata) # 构建Resquest对象
req.add_header('User-Agent','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45')
data = urllib.request.urlopen(req).read() #登录并爬取对应的网页
fhandle = open('/home/wk/csdn1.html','wb')
fhandle.write(data)
fhandle.close()
url2 = "http://bbs.chinaunix.net/" # 设置要爬取的该网站下其他网页地址
req2 = urllib.request.Request(url2, postdata)
req2.add_header('User-Agent','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45')
data2 = urllib.request.urlopen(req2).read() # 爬取该站下的其他网页
fhandle2 = open('/home/wk/csdn.html','wb')
fhandle2.write(data2)
fhandle2.close()
1.使用urllib.request.Request()创建对象
2.add_header添加头部信息,这里添加代理信息
3.urllib.request.urlopen().read()登录打开网站并读取内容
4.文件操作,保存网页到本地
5.登录后再爬取该网页下的其他网页,并保存本地
总结:打开第一个保存的网页,发现其已经是在登录状态,但打开第二个网页,它是要重新登录才能进去的。这是因为我们没有设置cookie,使其会话信息一直保存。
使用cookie登录
# -*- coding:UTF-8 -*-
import urllib.request
import urllib.parse
import http.cookiejar
url = "http://bbs.chinaunix.net/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LfgTz"
postdata = urllib.parse.urlencode({ # 此处登录可用自己在网站上注册的用户名和密码
"username": "weisuen",
"password": "aA123456"
}).encode("utf-8")
req = urllib.request.Request(url, postdata)
req.add_header('User-Agent','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45')
# 使用http.cookiejar.CookieJar()创建CookieJar对象
cjar = http.cookiejar.CookieJar()
# 使用HTTPCookieProcessor创建cookie处理器,并以其参数构建opener对象
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cjar))
# 将opener安装为全局
urllib.request.install_opener(opener)
file = opener.open(req)
data = file.read()
file = open('/home/wk/csdn.html','wb')
file.write(data)
file.close()
url2 = "http://bbs.chinaunix.net/" # 设置要爬取的该网站下其他网页地址
data2 = urllib.request.urlopen(url2).read()
fhandle = open('/home/wk/csdn1.html','wb')
fhandle.write(data2)
fhandle.close()