python接口自动化24-token关联登录
前言
登录网站的时候,经常会遇到传token参数,token关联并不难,难的是找出服务器第一次返回token的值所在的位置,取出来后就可以动态关联了
登录拉勾网
1.先找到登录首页https://passport.lagou.com/login/login.html, 输入账号和密码登录,抓包看详情
2.再重新登录一次抓包看的时候,头部有两个参数是动态的,token和code值每次都会不一样,只能用一次
X-Anit-Forge-Token: 45aa69d8-4afa-4235-8957-9dde7af1903e
X-Anit-Forge-Code: 20765316
找到token生成的位置
1.打开登录首页https://passport.lagou.com/login/login.html,直接按F5刷新(只做刷新动作,不输入账号和密码),然后从返回的页面找到token生成的位置
看注释内容:
</script>
<!-- 页面样式 --> <!-- 动态token,防御伪造请求,重复提交 -->
<script>
window.X_Anti_Forge_Token = '286fd3ae-ef82-4019-89c4-9408947a0e26';
window.X_Anti_Forge_Code = '74603111';
</script>
前端的代码,注释内容暴露了token位置,嘿嘿!
2.接下来从返回的html里面解析出token和code两个参数的值
# coding:utf-8 import requests import re from bs4 import BeautifulSoup def getTokenCode(s): ''' 要从登录页面提取token,code, 然后在头信息里面添加 <!-- 页面样式 --><!-- 动态token,防御伪造请求,重复提交 --> <script type="text/javascript"> window.X_Anti_Forge_Token = 'dde4db4a-888e-47ca-8277-0c6da6a8fc19'; window.X_Anti_Forge_Code = '61142241'; </script> # 作者:上海- 悠悠 QQ群:588402570 ''' url = 'https://passport.lagou.com/login/login.html' h = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0", } # 更新session的headers s.headers.update(h) data = s.get(url, verify=False) soup = BeautifulSoup(data.content, "html.parser", from_encoding='utf-8') tokenCode = {} try: t = soup.find_all('script')[1].get_text() print(t) tokenCode['X-Anit-Forge-Token'] = re.findall(r"Token = '(.+?)'", t)[0] tokenCode['X_Anti_Forge_Code'] = re.findall(r"Code = '(.+?)'", t)[0] except: print("获取token和code失败") tokenCode['X-Anit-Forge-Token'] = "" tokenCode['X_Anti_Forge_Code'] = "" return tokenCode
模拟登陆
1.登陆的时候这里密码参数虽然加密了,但是是固定的加密方式,所以直接复制抓包的加密后字符串就行了
# coding:utf-8 import requests import re from bs4 import BeautifulSoup def login(s, gtoken, user, psw): ''' function:登录拉勾网网站 :param s: 传s = requests.session() :param gtoken: 上一函数getTokenCode返回的tokenCode :param user: 账号 :param psw: 密码 :return: 返回json ''' url2 = 'https://passport.lagou.com/login/login.json' h2 = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "X-Requested-With": "XMLHttpRequest", "X-Anit-Forge-Token": gtoken['X-Anit-Forge-Token'], "X-Anit-Forge-Code": gtoken['X-Anit-Forge-Code'], "Referer": "https://passport.lagou.com/login/login.html", } # 更新s的头部 s.headers.update(h2) body = { "isValidate":'true', "username": user, "password": psw, "request_form_verifyCode": "", "submit": "" } r2 = s.post(url2 , data=body, verify=False) print(r2.text) return r2.json()
密码加密
1.这里密码是md5加密的(百度看了其它大神的博客,才知道的)
# coding:utf-8 import requests import re from bs4 import BeautifulSoup import hashlib def encryptPwd(passwd): # 对密码进行了md5双重加密 passwd = hashlib.md5(passwd.encode('utf-8')).hexdigest() # veennike 这个值是在js文件找到的一个写死的值 passwd = 'veenike'+passwd+'veenike' passwd = hashlib.md5(passwd.encode('utf-8')).hexdigest() return passwd if __name__ == "__main__": # 测试密码123456 print(encryptPwd("123456"))
输出结果:
.
2.跟抓包的数据对比,发现是一样的,说明加密成功
参考代码:
1 # coding:utf-8 2 import requests 3 import re 4 from bs4 import BeautifulSoup 5 import urllib3 6 import hashlib 7 urllib3.disable_warnings() 8 9 class LoginLgw(): 10 11 12 def __init__(self, s): 13 self.s = s 14 15 def getTokenCode(self): 16 ''' 17 要从登录页面提取token,code, 然后在头信息里面添加 18 <!-- 页面样式 --><!-- 动态token,防御伪造请求,重复提交 --> 19 <script type="text/javascript"> 20 window.X_Anti_Forge_Token = 'dde4db4a-888e-47ca-8277-0c6da6a8fc19'; 21 window.X_Anti_Forge_Code = '61142241'; 22 </script> 23 ''' 24 url = 'https://passport.lagou.com/login/login.html' 25 h = { 26 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0", 27 } 28 # 更新session的headers 29 self.s.headers.update(h) 30 data = self.s.get(url, verify=False) 31 soup = BeautifulSoup(data.content, "html.parser", from_encoding='utf-8') 32 tokenCode = {} 33 try: 34 t = soup.find_all('script')[1].get_text() 35 print(t) 36 tokenCode['X_Anti_Forge_Token'] = re.findall(r"Token = '(.+?)'", t)[0] 37 tokenCode['X_Anti_Forge_Code'] = re.findall(r"Code = '(.+?)'", t)[0] 38 return tokenCode 39 except: 40 print("获取token和code失败") 41 tokenCode['X_Anti_Forge_Token'] = "" 42 tokenCode['X_Anti_Forge_Code'] = "" 43 return tokenCode 44 45 def encryptPwd(self,passwd): 46 # 对密码进行了md5双重加密 47 passwd = hashlib.md5(passwd.encode('utf-8')).hexdigest() 48 # veennike 这个值是在js文件找到的一个写死的值 49 passwd = 'veenike'+passwd+'veenike' 50 passwd = hashlib.md5(passwd.encode('utf-8')).hexdigest() 51 return passwd 52 53 def login(self, user, psw): 54 ''' 55 function:登录拉勾网网站 56 :param user: 账号 57 :param psw: 密码 58 :return: 返回json 59 ''' 60 gtoken = self.getTokenCode() 61 print(gtoken) 62 print(gtoken['X_Anti_Forge_Token']) 63 print(gtoken['X_Anti_Forge_Code']) 64 url2 = 'https://passport.lagou.com/login/login.json' 65 h2 = { 66 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0", 67 "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 68 "X-Requested-With": "XMLHttpRequest", 69 "X-Anit-Forge-Token": gtoken['X_Anti_Forge_Token'], 70 "X-Anit-Forge-Code": gtoken['X_Anti_Forge_Code'], 71 "Referer": "https://passport.lagou.com/login/login.html", 72 } 73 74 # 更新s的头部 75 self.s.headers.update(h2) 76 passwd = self.encryptPwd(psw) 77 78 body = { 79 "isValidate":'true', 80 "username": user, 81 "password": passwd, 82 "request_form_verifyCode": "", 83 "submit": "" 84 } 85 r2 = self.s.post(url2 , data=body, verify=False) 86 try: 87 print(r2.text) 88 return r2.json 89 except: 90 print("登录异常信息:%s" % r2.text) 91 return None 92 93 if __name__ == "__main__": 94 s = requests.session() 95 lgw = LoginLgw(s) 96 lgw.login("15221000000", "123456")