-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gitee的模拟登录考虑加吗? #114
Comments
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 = "SvenAugustus@outlook.com"
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 测试了一下 在你 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No description provided.
The text was updated successfully, but these errors were encountered: