基础知识
在这里需要知道一些基础知识,才能理解本文的内容,若只想实现功能可跳过本部分
什么是Session
在上一篇文章中,我们讲解了Cookie,Cookie是每次请求都会有的东西,也就意味着每次免密登录,都需要把cookie带上,那就与输入账号密码的登录方式没区别了,有没有更加简单的方法呢?这时候就需要用到Session了
Session是服务器为了保存用户状态而创建的一个特殊的对象。
简单的理解,cookie相当于把身份信息写在一张纸上,每次身份认证都需要拿出来,一次性的,session相当于代表了你身份信息的衣服,比如皇帝的龙袍,大臣看见穿黄袍的就认为他是皇帝,龙袍也就相当于持续性的cookie(其实session还能保存除cookie以外的信息)
requests 库中session的创建与使用
创建
# 这样就创建了一个session对象
session = requests.session()
使用
# 这里就能设置通过session访问页面的headers信息
session.headers = headers
# 通过session发送get请求
session.get(url=url)
# 通过session发送post请求 datas是post给url的key-word数据
session.post(url=url,data=datas)
准备工作
这部分暂时省略,因为GitHub在登录时,提交给服务器的除了账号密码之外,还有许多字段名、字段值需要构建,其中有四个并不固定,需要到一个静态html中取寻找。
代码部分
# 302 重定向
import requests
import re
'''
分析可知 三个字段的值 都可以从https://github.com/login中找到
authenticity_token: value
timestamp: value
timestamp_secret: value
另外一个 required_field_xxxx: name 的xxxx 也是这个界面中找到
总体流程
1.给login发请求 获取四个字段
2.给session发请求登录
'''
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.95 Safari/537.36'
}
class GitHubLogin(object):
def __init__(self):
super(GitHubLogin, self).__init__()
self.url1 = "https://github.com/login"
self.url2 = "https://github.com/session"
self.url3 = "https://github.com/fhwq"
self.session = requests.session()
self.session.headers = headers
@staticmethod
def getKeyWord(url: str, Obj: requests.Session) -> dict:
response1 = Obj.get(url=url, verify=False).content.decode()
# print(response1)
KW = {
}
# 正则表达式提取 使用分组 直接获取匹配部分
token = re.findall('name="authenticity_token" value="(.*?)" />', response1)[0]
required_field = \
re.findall('<input type="text" name="(.*?)" hidden="hidden" class="form-control" />', response1)[0]
timestamp = re.findall('name="timestamp" value="(.*?)"', response1)[0]
timestamp_secret = re.findall('name="timestamp_secret" value="(.*?)"', response1)[0]
KW[required_field] = ""
KW["timestamp"] = timestamp
KW["timestamp_secret"] = timestamp_secret
KW["authenticity_token"] = token
return KW
def setName(self, Name: str):
self.url3 = "https://github.com/" + Name
def login(self, account: str, pwd: str):
data = self.getKeyWord(self.url1, self.session)
data["commit"] = "Sign in"
data["webauthn-support"] = "supported"
data["webauthn-iuvpaa-support"] = "unsupported"
data["return_to"] = "https://github.com/login"
data["allow_signup"] = ""
data["client_id"] = ""
data["integration"] = ""
data["login"] = account
data["password"] = pwd
# 这里通过session post出去后 session会自动保持响应的cookie等信息
self.session.post(url=self.url2, data=data)
# 开始用session 等同于 requests.get(url=url3,cookies)
self.result = self.session.get(self.url3)
with open("session_github.html", "wb") as f:
f.write(self.result.content)
if __name__ == "__main__":
login = GitHubLogin()
login.setName("你的名字")
login.login("你的账号", "你的密码")
在第一次使用session.post后,session中就自动保存了cookie等信息,在这之后,无论进行多少次session.get,都会自动携带cookie,也就实现了重复免密登录,且不需要再设置除url外的任何参数,值得注意的是,每个cookie会有一个有效时限,若过期了就需要重新获取。许多网站上,都会有一个 七天免密码登录 选项就是这么的原理。