我们经常有这样的上网经历,就是如果你采用用户名密码登陆一个网站之后,如果在一段不长的时间内,再次访问这个本来需要你登陆的网站,你会很轻易地访问,而不需要再次输入用户名密码。这种“免登陆”的体验无疑给用户带来了非常好的体验,那为什么会“免登陆”呢?是什么在起作用呢?
答案就是Cookie。当我们在浏览器内输入url,浏览器会向服务器发送一个HTTP请求,相应的,服务器会响应这个请求,向浏览器返回响应的响应信息。所谓Cookie,可以简单认的为是在浏览器端记录包括登陆状态在内的各种属性值的容器名称,其实就是服务器为了保持浏览器与服务器之间连通状态,而在用户本地上创建的数据。只要用户再一次登陆,服务器会主动地寻找这些预存的数据,而无需再要求像第一次一样的操作。
在前面,我们都是使用的默认的opener,也就是urlopen。它是一个特殊的opener,可以理解成opener的一个特殊实例,传入的参数仅仅是url,data,timeout。
如果我们需要用到Cookie,只用这个opener是不能达到目的的,所以我们需要创建更一般的opener来实现对Cookie的设置。
(1)方法一使用requests模块:
使用requests.session()。
示例如下:
import requests
s = requests.session() # 可以在多次访问中保留cookie
s.post(login_url, {'username':username, 'password': password,}, headers=headers) # POST帐号和密码,设置headers
r = s.get(url) # 已经是登录状态了
仍然以登录厦门大学师生系统为例,这回我们登录并进入到查看成绩的页面,返回页面信息。
import requests
#实际登录页面
login_url = 'http://ssfw.xmu.edu.cn/cmstar/userPasswordValidate.portal'
#查询成绩页面
grade_url = 'http://ssfw.xmu.edu.cn/cmstar/index.portal?.pn=p1201_p3535'
user_agent = r'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36'
headers = {'User-Agnet': user_agent, 'Connection': 'keep-alive'}
#用户信息
Login_Data = {}
Login_Data['Login.Token1'] = '帐号'
Login_Data['Login.Token2'] = '密码'
Login_Data['goto'] = 'http: // ssfw.xmu.edu.cn / cmstar / loginSuccess.portal'
Login_Data['gotoOnFail'] = 'http: // ssfw.xmu.edu.cn / cmstar / loginFailure.portal'
# 使用session方法,可以在多次访问中保留cookie
requests_session = requests.session()
response1 = requests_session.post(url=login_url, data=Login_Data, headers=headers)
html1 = response1.text
response2 = requests_session.get(url=grade_url)
html2 = response2.text
print(html2)
看下结果,确实返回了成绩查询的html,说明cookie登录成功。
(2)方法二使用urllib、http.cookiejar模块:
首先,我们先利用http.cookieJar对象实现获取cookie的功能,存储到变量中,这基本上就是我们用方法二cookie登录的模板了。
from urllib import request
from http import cookiejar
#声明一个CookieJar对象实例来保存cookie
cookie = cookiejar.CookieJar()
#利用urllib.request库的HTTPCookieProcessor对象来创建cookie处理器,也就CookieHandler
handler=request.HTTPCookieProcessor(cookie)
#通过CookieHandler创建opener
opener = request.build_opener(handler)
#此处的open方法打开网页
response = opener.open('http://www.baidu.com')
#打印cookie信息
for item in cookie:
print('Name = %s' % item.name)
print('Value = %s' % item.value)
输出显示为:
以登录厦门大学师生系统为例,登录并进入到查看成绩的页面,返回页面信息。
from urllib import request
from urllib import parse
from http import cookiejar
#Fiddler获得的真实登陆地址
login_url = 'http://ssfw.xmu.edu.cn/cmstar/userPasswordValidate.portal'
user_agent = r'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36'
#Headers信息
headers = {'User-Agnet': user_agent, 'Connection': 'keep-alive'}
#登陆Form_Data信息
Login_Data = {}
Login_Data['Login.Token1'] = '帐号'
Login_Data['Login.Token2'] = '密码'
Login_Data['goto'] = 'http: // ssfw.xmu.edu.cn / cmstar / loginSuccess.portal'
Login_Data['gotoOnFail'] = 'http: // ssfw.xmu.edu.cn / cmstar / loginFailure.portal'
#使用urlencode方法转换标准格式
logingpostdata = parse.urlencode(Login_Data).encode('utf-8')
#声明一个CookieJar对象实例来保存cookie
cookie = cookiejar.CookieJar()
#利用urllib.request库的HTTPCookieProcessor对象来创建cookie处理器,也就CookieHandler
cookie_support = request.HTTPCookieProcessor(cookie)
#通过CookieHandler创建opener
opener = request.build_opener(cookie_support)
#创建Request对象
req1 = request.Request(url=login_url, data=logingpostdata, headers=headers)
#打开登陆界面
html1 = opener.open(req1)
#print(html1.read().decode('utf-8'))
#查询成绩的页面
grade_url = 'http://ssfw.xmu.edu.cn/cmstar/index.portal?.pn=p1201_p3535'
req2 = request.Request(url=grade_url, headers=headers)
html2 = opener.open(req2)
html2 = html2.read().decode('utf-8')
print(html2)
(3)页面处理
如果再用一些网页源代码的处理方法,比如正则表达式,或者BeautifulSoup工具,我们可以进一步对获得的页面进行处理。这里对requests模块的代码进行了一下调整,用正则表达式对成绩进行了绩点的统计和学分的统计。
# -*- coding: UTF-8 -*-
import re
import requests
#打开登录页面
def login_html(url):
user_agent = r'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36'
headers = {'User-Agnet': user_agent, 'Connection': 'keep-alive'}
Login_Data = {}
Login_Data['Login.Token1'] = '帐号'
Login_Data['Login.Token2'] = '密码'
Login_Data['goto'] = 'http: // ssfw.xmu.edu.cn / cmstar / loginSuccess.portal'
Login_Data['gotoOnFail'] = 'http: // ssfw.xmu.edu.cn / cmstar / loginFailure.portal'
requests_session = requests.session()
response = requests_session.post(url=url, data=Login_Data, headers=headers)
response.encoding = 'utf-8'
html = response.text
return requests_session, html
#打开需要登陆后才能访问的页面
def grade_html(requests_session, grade_url):
response = requests_session.get(url=grade_url)
html = response.text
#print(html)
return html
#正则表达式提取成绩信息
def rule(html):
reg = re.compile(r'<td width="260px">.*?<font color="">(.*?)</font> .*?<font color="">(.*?)</font> .*?<font color="">(.*?)</font> .*?<font color="">(.*?)</font> .*?<font color="">(.*?)</font> .*?<font color="">(.*?)</font> .*?<td width="70px">',re.S)
grade = re.findall(reg, html)
for i in grade:
print(i)
return grade
#绩点计算方法
def gpa(x):
if x >= 90:
return 4.0
elif x >= 85:
return 3.7
elif x >= 81:
return 3.3
elif x >= 78:
return 3.0
elif x >= 75:
return 2.7
elif x >= 72:
return 2.3
elif x >= 68:
return 2.0
elif x >= 68:
return 1.7
elif x >= 68:
return 1.0
else:
return 0
#绩点统计和学分统计
def grade_count(grade):
m,n,k = 0,0,0
for i in grade:
if i[2] == '通识教育' or not i[4].isdigit() or i[5]=='免修':
k += float(i[1])
continue
m += gpa(float(i[4]))*float(i[1])
n += float(i[1])
k += float(i[1])
print('去除“通识教育”后的绩点:',m/n,'总学分:',k)
dic = {}
for i in grade:
dic[i[2]] = 0
for i in grade:
dic[i[2]] = dic[i[2]] + float(i[1])
print(dic)
if __name__ == '__main__':
#登录url
login_url = 'http://ssfw.xmu.edu.cn/cmstar/userPasswordValidate.portal'
#成绩查询url
grade_url = 'http://ssfw.xmu.edu.cn/cmstar/index.portal?.pn=p1201_p3535'
requests_session, html1 = login_html(login_url)
html2 = grade_html(requests_session, grade_url)
grade = rule(html2)
grade_count(grade)
看一下运行结果。
PS:
正则表达式的应用可以参考:
(1) http://cuiqingcai.com/977.html
(2) http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
BeautifulSoup可以参考:
(1) http://cuiqingcai.com/1319.html
参考:
(1) http://blog.csdn.net/c406495762/article/details/69817490
(2) http://cuiqingcai.com/968.html
(3)宁哥的小站-COOKIE登录
网友评论