awesome-python-login-model
awesome-python-login-model copied to clipboard
gitee的模拟登录考虑加吗?
import requests
import re
import base64
# pip uninstall pycrypto
# pip install pycryptodome
# pip install Crypto
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
# python2 和 python3的兼容代码
try:
# python2 中
import cookielib
except:
# python3 中
import http.cookiejar as cookielib
class GiteeLogin(object):
def __init__(self, username, password):
# 初始化信息
self.headers = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
"Connection": "keep-alive",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "gitee.com",
"Origin": "https://gitee.com",
"Referer": "https://gitee.com/login",
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36",
}
# session代表某一次连接
self.session = requests.Session()
self.profile_url = 'https://gitee.com/profile'
self.post_url = 'https://gitee.com/login'
self.token_url = 'https://gitee.com/login'
self.encryptCsrfToken = None
self.encryptSeparator = None
self.publicKey = None
self.username = username
self.password = password
self.token = None
# 因为原始的session.cookies 没有save()方法,所以需要用到cookielib中的方法LWPCookieJar,这个类实例化的cookie对象,就可以直接调用save方法。
self.session.cookies = cookielib.LWPCookieJar(filename="giteeCookie.txt")
# 登录入口
def tryLogin(self):
# 第一步:尝试使用已有的cookie登录
try:
self.session.cookies.load()
except:
print(f"Failed to load cookie.")
isLogin = self.isLoginStatus()
print(f"isLogin = {isLogin}")
if isLogin == False:
return self.login()
return True
# 通过访问个人中心页面的返回状态码来判断是否为登录状态
def isLoginStatus(self):
# 下面有两个关键点
# 第一个是header,如果不设置,会返回500的错误
# 第二个是allow_redirects,如果不设置,session访问时,服务器返回302,
# 然后session会自动重定向到登录页面,获取到登录页面之后,变成200的状态码
# allow_redirects = False 就是不允许重定向
resp = self.session.get(self.profile_url, headers=self.headers, allow_redirects=False)
if resp.status_code != 200:
# print(f"Login Status, StatusCode = {resp.status_code}")
return False
else:
return True
# 登录入口
def login(self):
ok = self.prepare()
if ok == False:
return False
plainStringText = '' + self.encryptCsrfToken + self.encryptSeparator + self.password
formatPublicKey = self.publicKey.replace('\\n', '\n')
encryptPassword = self.encryptStringByRSA(formatPublicKey, plainStringText)
# print( self.encryptCsrfToken )
# print( self.encryptSeparator )
# print( self.password )
postData = {
"encrypt_key": "password",
"utf8": "✓",
"authenticity_token": self.token,
"redirect_to_url": "",
"user[login]": self.username,
"encrypt_data[user[password]]": encryptPassword,
"user[remember_me]": "0"
}
# print(postData)
resp = self.session.post(self.post_url, data=postData, headers=self.headers)
if resp.status_code != 200:
print(f"Login Fail, StatusCode = {resp.status_code}")
return False
# print(f"Text = {resp.text}")
index = resp.text.index('action="/login"')
if index >= 0:
return False
# 登录成功之后,将cookie保存在本地文件中
self.session.cookies.save()
return True
def prepare(self):
resp = self.session.get(self.token_url, headers=self.headers)
if resp.status_code != 200:
print(f"Prepare Fail, StatusCode = {resp.status_code}")
return None
ok = self.parseKey(resp.text)
if ok == False:
return False
ok = self.parseToken(resp.text)
if ok == False:
return False
return True
# Get login token
def getToken(self):
if self.token == None:
resp = self.session.get(self.token_url, headers=self.headers)
if resp.status_code != 200:
print(f"Get Token Fail, StatusCode = {resp.status_code}")
return None
self.parseToken(resp.text)
return self.token
# parse key
def parseKey(self, text):
match = re.search(r'meta content="(.*?)" name="csrf-token"', text)
if not match:
print('Get Encrypt Csrf Token Fail')
return False
else:
self.encryptCsrfToken = match.group(1)
match = re.search(r'"separator":"(.*?)"', text)
if not match:
print('Get Encrypt separator Fail')
return False
else:
self.encryptSeparator = match.group(1)
match = re.search(r'"password_key":"(.*?)"', text)
if not match:
print('Get Public Key Fail')
return False
else:
self.publicKey = match.group(1)
return True
# parse token
def parseToken(self, text):
match = re.search(r'name="authenticity_token" type="hidden" value="(.*?)"', text)
if not match:
print('Get Csrf Token Fail')
return False
self.token = match.group(1)
return True
# RSA 加密
def encryptStringByRSA(self, publicKey, plainStringText):
rsa_key = RSA.import_key(publicKey)
cipher = PKCS1_OAEP.new(rsa_key)
x = cipher.encrypt(plainStringText.encode())
return base64.b64encode(x).decode()
def force_sync_project(self, postUrl):
postData = {
"user_sync_code": "",
"password_sync_code": "",
"sync_wiki": "false",
"authenticity_token": self.getToken()
}
resp = self.session.post(postUrl, data=postData, headers=self.headers, allow_redirects=False)
if resp.status_code != 200:
print(f"Failed to Force Sync Project, StatusCode = {resp.status_code}")
print(f"Text = {resp.text}")
else:
print(f"Successful to Force Sync Project")
if __name__ == "__main__":
# 用户名,密码请修改
username = "[email protected]"
password = "XXX"
login = GiteeLogin(username, password)
status = login.tryLogin()
if status == True:
login.force_sync_project("https://gitee.com/svenaugustus/dubbo/force_sync_project")
else:
print(f"Login Fail")
我自己写的python脚本,登录没成功 o(╯□╰)o
@SvenAugustus 可以尝试,不太确定哦。
@SvenAugustus 测试了一下
在你 post
登录前你可以尝试发送请求到 https://gitee.com/check_user_login
验证一下
如果再响应体中出现 {"result":1,"failed_count":2}
这种信息,那就是说要需要输入验证码了,这时候需要去请求验证码,然后在 login post data 中添加 captcha 参数,其中填写请求下来的验证码。