一、需要使用requests下的會話對象;
會話對象讓你能夠跨請求保持某些參數。它也會在同一個Session實例發出的所有請求之間保持cookie。
方法級別的參數不會被跨請求保持。
參考:https://requests.readthedocs.io/zh_CN/latest/user/advanced.html#session-objects
二、查看禪道源碼,發現需要對密碼、rand進行md5加密,且在登錄時,需要傳入變量verifyRand;下圖可以確定rand==verifyRand;



三、提取rand;通過fiddler抓包,發現登錄頁面有rand值,但通過接口請求的rand值的長度不固定,目前發現長度有9位、10位的;
所以判斷提取的長度為10時,則不再請求登錄接口;

四、md5加密密碼、rand
import hashlib
#方式一
hash=hashlib.md5()
hash.update('P@ssw0rd'.encode('utf-8'))#不添加.encode('utf-8')會報錯
f=hash.hexdigest()+str(1268292672)#web登錄,fiddler抓包到的rand值
#print(f)
#方式二
hash2=hashlib.md5(f.encode('utf-8'))
s=hash2.hexdigest()
print(s)#查看加密后的值與fiddler傳遞的密碼應該是相同的
五、判斷登錄是否成功;
fiddler抓包查看登錄成功的響應內容,發現不太容易判斷,所以再次請求一個其他頁面,判斷是否有退出;

fiddler抓包http://localhost/zentaopms/www/bug-browse-6.html請求,部分響應內容如下;


六、登錄禪道參考代碼
# coding:utf-8
import requests
import re
import hashlib
pw="P@ssw0rd"
s=requests.Session()
headers={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"
}
vrand=0
while(True):
rs1=s.get("http://localhost/zentaopms/www/user-login.html",headers=headers)
rs1.encoding='utf-8'
#print(rs1.text)
rand=re.findall(r"'verifyRand' value='(.+?)'",rs1.text)
#print(rand[0])
if len(rand[0])==10:
vrand=rand[0]
break
print(vrand)
#方式一
hash=hashlib.md5()
hash.update(pw.encode('utf-8'))
f=hash.hexdigest()+vrand
#print(f)
#方式二
hash2=hashlib.md5(f.encode('utf-8'))
pwd=hash2.hexdigest()
print(pwd)
data={
"account":"fuhui",
"password":pwd,
"referer":"http://localhost/zentaopms/www/bug-browse-6.html",
"verifyRand":vrand
}
rs2=s.post("http://localhost/zentaopms/www/user-login.html",headers=headers,data=data)
rs2.encoding='utf-8'
#print(rs2.text)
rs3=s.get("http://localhost/zentaopms/www/bug-browse-6.html",headers=headers)
rs3.encoding='utf-8'
#print(rs3.text)
result=re.findall(r"\<a href=\'\/zentaopms\/www\/user-logout.html' \>(.+?)\<\/a\>",rs3.text)
print(result)
if result[0]=="退出":
print("登錄成功")
運行結果截圖如下:

