python爬虫之urllib库(三)
urllib库
访问网页都是通过HTTP协议进行的,而HTTP协议是一种无状态的协议,即记不住来者何人。举个栗子,天猫上买东西,需要先登录天猫账号进入主页,再去选择商品。HTTP的无状态性表现在,登录账号以后进入主页,再进入商品页面的时候,你又必须重新登录。这就是HTTP协议的无状态性,你通过HTTP发送请求,服务器接收的当前请求,处理后让你进入主页,当你选择商品要进入商品页面的时候,服务器就又不认识你是谁了,只会问:来者何人?来,登录表单再发你,填吧。那现在根本不是我说的这种情况,现在我打开天猫,登录一次到shopping完成,都没有再次login,这说明了存在某种东西在帮助HTTP记着来者的身份,某种东西就是Cookie+Session或者Token!
Session
当客户端向服务器发送登录HTTP请求时,服务器会使用Session把用户信息临时保存在服务器端,保存的同时会生成一个身份标识,即SessionID。服务器把SessionID发给客户端,告诉客户端:“这段时间这就是你来我这儿的门卡”,客户端保存着它的门卡,后面每一次请求都带着“门卡”访问服务器,服务器也通过“门卡”记住了客户端。用户注销了网站登录,那Session自然也会销毁了。
Cookie
当客户端向服务器发送登录HTTP请求时,服务器会在HTTP响应头headers中设置Set-Cookie首部信息,服务器的意思就是告诉客户端:“你按照一定规范把你用户信息保存在你那吧,以后再来我这儿带给我看你存的东西就成了”,客户端接收HTTP响应以后,看到服务器在响应中的Set-Cookie信息,明白了服务器的意思,以文本形式保存了用户信息等,在以后的每一次请求中,客户端发送的HTTP请求都会在headers中添加Cookie首部信息,告诉服务器我是带着我的用户信息来的,那自然服务器就记住了客户端。
Cookie+Session
前面提到了Session中会产生一个SessionID来作为身份验证,Session会把用户信息保存在服务器;Cookie是把用户信息保存在客户端,以Cookie保存的用户信息作为身份验证。Cookie+Session就是Cookie在客户端保存的不再是用户信息那么大的数据了,只保存SessionID,以后Cookie就带着SessionID去访问服务器就OK。从客户端和服务端来说是减轻了客户端的压力。
Token
当客户端向服务器发送登录HTTP请求,服务器会把用户信息生成一个Token,并且使用加密算法为Token生成一个签名,然后把带签名的Token信息发送给客户端保存起来。客户端后面的请求都会在HTTP请求headers中加上Token信息,服务器接收到以后先解密Token的签名,然后就记住了客户端。
Cookiejar
为爬虫添加Cookie是为了使爬取网站内多个网页内容时,可以保持登录状态持续爬取。python2中使用Cookielib库添加Cookie,而python3使用Cookiejar处理。
不使用Cookie的情况
import urllib.requestimport urllib.parseurl = 'https://www.yaozh.com/login'headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36'}data = { 'username': 'snow_1', 'pwd': 'bushizhendemima'}post_data = urllib.parse.urlencode(data).encode('utf-8')req = urllib.request.Request(url, data=post_data,headers=headers)rep = urllib.request.urlopen(req).read()with open('1.html', 'wb') as f: f.write(rep)url_next = 'https://www.yaozh.com/'req_next = urllib.request.Request(url, data=post_data,headers=headers)rep_next = urllib.request.urlopen(req_next).read()with open('2.html', 'wb') as f: f.write(rep_next)
使用Cookie的情况
import urllib.requestimport urllib.parseimport http.cookiejarurl = 'https://www.yaozh.com/login'headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36'}data = { 'username': 'snow_1', 'pwd': 'bushizhendemima'}post_data = urllib.parse.urlencode(data).encode('utf-8')req = urllib.request.Request(url, data=post_data,headers=headers)cookie = http.cookiejar.CookieJar() # 实例CookieJar对象processor = urllib.request.HTTPCookieProcessor(cookie) # 创建cookie处理器opener = urllib.request.build_opener(processor) # 构建opener对象urllib.request.install_opener(opener) # 安装openner为全局rep = opener.open(req).read()with open('1.html', 'wb') as f: f.write(rep)url_next = 'https://www.yaozh.com/'rep_next = urllib.request.urlopen(url_next).read()with open('2.html', 'wb') as f: f.write(rep_next)
使用Cookie就不需要在多次请求都添加数据,即Request类的data属性。