import re import os import json import requests s = requests.Session() # cookies序列化文件 COOKIES_FILE_PATH = 'taobao_login_cookies.txt' class UsernameLogin: def __init__(self, username, ua, TPL_password2): """ 帳號登陸對象 :param username: 用戶名 :param ua: 淘寶的ua參數 :param TPL_password2: 加密後的密碼 """ # 檢測是否須要驗證碼的URL self.user_check_url = 'https://login.taobao.com/member/request_nick_check.do?_input_charset=utf-8' # 驗證淘寶用戶名密碼URL self.verify_password_url = "https://login.taobao.com/member/login.jhtml" # 訪問st碼URL self.vst_url = 'https://login.taobao.com/member/vst.htm?st={}' # 淘寶我的 主頁 self.my_taobao_url = 'http://i.taobao.com/my_taobao.htm' # 淘寶用戶名 self.username = username # 淘寶關鍵參數,包含用戶瀏覽器等一些信息,不少地方會使用,從瀏覽器或抓包工具中複製,可重複使用 self.ua = ua # 加密後的密碼,從瀏覽器或抓包工具中複製,可重複使用 self.TPL_password2 = TPL_password2 # 請求超時時間 self.timeout = 3 def _user_check(self): """ 檢測帳號是否須要驗證碼 :return: """ data = { 'username': self.username, 'ua': self.ua } try: response = s.post(self.user_check_url, data=data, timeout=self.timeout) response.raise_for_status() except Exception as e: print('檢測是否須要驗證碼請求失敗,緣由:') raise e needcode = response.json()['needcode'] print('是否須要滑塊驗證:{}'.format(needcode)) return needcode def _verify_password(self): """ 驗證用戶名密碼,並獲取st碼申請URL :return: 驗證成功返回st碼申請地址 """ verify_password_headers = { 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', 'Origin': 'https://login.taobao.com', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36', 'Content-Type': 'application/x-www-form-urlencoded', 'Referer': 'https://login.taobao.com/member/login.jhtml?from=taobaoindex&f=top&style=&sub=true&redirect_url=https%3A%2F%2Fi.taobao.com%2Fmy_taobao.htm', } # 登陸toabao.com提交的數據,若是登陸失敗,能夠從瀏覽器複製你的form data verify_password_data = { 'TPL_username': self.username, 'ncoToken': 'cdf05a89ad5104403ebb12ebc9b7626af277b066', 'slideCodeShow': 'false', 'useMobile': 'false', 'lang': 'zh_CN', 'loginsite': 0, 'newlogin': 0, 'TPL_redirect_url': 'https://s.taobao.com/search?q=%E9%80%9F%E5%BA%A6%E9%80%9F%E5%BA%A6&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.2017.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170306', 'from': 'tb', 'fc': 'default', 'style': 'default', 'keyLogin': 'false', 'qrLogin': 'true', 'newMini': 'false', 'newMini2': 'false', 'loginType': '3', 'gvfdcname': '10', 'gvfdcre': '68747470733A2F2F6C6F67696E2E74616F62616F2E636F6D2F6D656D6265722F6C6F676F75742E6A68746D6C3F73706D3D61323330722E312E3735343839343433372E372E33353836363032633279704A767526663D746F70266F75743D7472756526726564697265637455524C3D6874747073253341253246253246732E74616F62616F2E636F6D25324673656172636825334671253344253235453925323538302532353946253235453525323542412532354136253235453925323538302532353946253235453525323542412532354136253236696D6766696C65253344253236636F6D6D656E64253344616C6C2532367373696425334473352D652532367365617263685F747970652533446974656D253236736F75726365496425334474622E696E64657825323673706D253344613231626F2E323031372E3230313835362D74616F62616F2D6974656D2E31253236696525334475746638253236696E69746961746976655F69642533447462696E6465787A5F3230313730333036', 'TPL_password_2': self.TPL_password2, 'loginASR': '1', 'loginASRSuc': '1', 'oslanguage': 'zh-CN', 'sr': '1440*900', 'osVer': 'macos|10.145', 'naviVer': 'chrome|76.038091', 'osACN': 'Mozilla', 'osAV': '5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36', 'osPF': 'MacIntel', 'appkey': '00000000', 'mobileLoginLink': 'https://login.taobao.com/member/login.jhtml?redirectURL=https://s.taobao.com/search?q=%E9%80%9F%E5%BA%A6%E9%80%9F%E5%BA%A6&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.2017.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170306&useMobile=true', 'showAssistantLink': '', 'um_token': 'T898C0FDF1A3CEE5389D682340C5F299FFE590F51543C8E3DDA8341C869', 'ua': self.ua } try: response = s.post(self.verify_password_url, headers=verify_password_headers, data=verify_password_data, timeout=self.timeout) response.raise_for_status() # 從返回的頁面中提取申請st碼地址 except Exception as e: print('驗證用戶名和密碼請求失敗,緣由:') raise e # 提取申請st碼url apply_st_url_match = re.search(r'<script src="(.*?)"></script>', response.text) # 存在則返回 if apply_st_url_match: print('驗證用戶名密碼成功,st碼申請地址:{}'.format(apply_st_url_match.group(1))) return apply_st_url_match.group(1) else: raise RuntimeError('用戶名密碼驗證失敗!response:{}'.format(response.text)) def _apply_st(self): """ 申請st碼 :return: st碼 """ apply_st_url = self._verify_password() try: response = s.get(apply_st_url) response.raise_for_status() except Exception as e: print('申請st碼請求失敗,緣由:') raise e st_match = re.search(r'"data":{"st":"(.*?)"}', response.text) if st_match: print('獲取st碼成功,st碼:{}'.format(st_match.group(1))) return st_match.group(1) else: raise RuntimeError('獲取st碼失敗!response:{}'.format(response.text)) def login(self): """ 使用st碼登陸 :return: """ # 加載cookies文件 if self._load_cookies(): return True # 判斷是否須要滑塊驗證 self._user_check() st = self._apply_st() headers = { 'Host': 'login.taobao.com', 'Connection': 'Keep-Alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' } try: response = s.get(self.vst_url.format(st), headers=headers) response.raise_for_status() except Exception as e: print('st碼登陸請求,緣由:') raise e # 登陸成功,提取跳轉淘寶用戶主頁url my_taobao_match = re.search(r'top.location.href = "(.*?)"', response.text) if my_taobao_match: print('登陸淘寶成功,跳轉連接:{}'.format(my_taobao_match.group(1))) self._serialization_cookies() return True else: raise RuntimeError('登陸失敗!response:{}'.format(response.text)) def _load_cookies(self): # 一、判斷cookies序列化文件是否存在 if not os.path.exists(COOKIES_FILE_PATH): return False # 二、加載cookies s.cookies = self._deserialization_cookies() # 三、判斷cookies是否過時 try: self.get_taobao_nick_name() except Exception as e: os.remove(COOKIES_FILE_PATH) print('cookies過時,刪除cookies文件!') return False print('加載淘寶登陸cookies成功!!!') return True def _serialization_cookies(self): """ 序列化cookies :return: """ cookies_dict = requests.utils.dict_from_cookiejar(s.cookies) with open(COOKIES_FILE_PATH, 'w+', encoding='utf-8') as file: json.dump(cookies_dict, file) print('保存cookies文件成功!') def _deserialization_cookies(self): """ 反序列化cookies :return: """ with open(COOKIES_FILE_PATH, 'r+', encoding='utf-8') as file: cookies_dict = json.load(file) cookies = requests.utils.cookiejar_from_dict(cookies_dict) return cookies def get_taobao_nick_name(self): """ 獲取淘寶暱稱 :return: 淘寶暱稱 """ headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' } try: response = s.get(self.my_taobao_url, headers=headers) response.raise_for_status() except Exception as e: print('獲取淘寶主頁請求失敗!緣由:') raise e # 提取淘寶暱稱 nick_name_match = re.search(r'<input id="mtb-nickname" type="hidden" value="(.*?)"/>', response.text) if nick_name_match: print('登陸淘寶成功,你的用戶名是:{}'.format(nick_name_match.group(1))) return nick_name_match.group(1) else: raise RuntimeError('獲取淘寶暱稱失敗!response:{}'.format(response.text)) if __name__ == '__main__': # 淘寶用戶名 username = '你的淘寶帳號' # 淘寶重要參數,從瀏覽器或抓包工具中複製,可重複使用 ua = ua = '119#Ml88qzses2GAoMMzEyFDngNzxSb0aF0jvLJis4SPegM+zO/SrpJmpXMemUBl9S9S2MxpMrnoOrOPEdmp49I4nuxDDsmz42k2MVJW3CkL9U+S4lkGqr32S/0QNEKCFo3T4BKUzs5L/U+g4NeVqrAFWs+XnRbGfoAzRBSedFN89COb/lFLdA7MMOT48oxm5rA1RZeedtNnfU+E471y0ZA8J5BVN88L9eFqwPsUcV58YUot19H7I0rORJVVNEFkfHDgsBB2XtN8gpV8zly3A3E8RmKVNEHT9dAzeIeUspq8fU+S4QR73eALR2PQNs829oASRBSUstN8fUVl4TLLdHR5R26ONNFLMsMXqmBhxiLmXUEbqCaZSCqOfoDGn9jm1VChfC0IYWImgkr3TXv97EmqlkrryajB6Sc4xGvCtn1i0TQSHqH9U//xgEcik+qYs0Hz6F05aod24o5E5w9R/y+SOzuzpj/2LFLbbKMir5vYriyUElW9jJRB3lWl29J1IzE9AkmXQUKvK17xi8m+XMfa/nQOqjNw+9xQ/shUYXNWrdSzn/p4aqAwyVAesSfwrTEM4CoYv8l3G4h6eHXfqkIkI5umAIT/IWyIB1h8pTUszi89IuJEgUnBrn99IzRkSj+LuzojDYzarl5Nz5zCpfO0245KbesCYq/0F7XJhMms61z1rXDvHDJaIsoPxa4WWGgoAp8S1Mt/TWfUw/DBADQgXiBxZFpvM7TyfhxOpP+ItvGnJoDu/9OPzZ8u3VVvskBJGoA1EKT63U+A5sHSlkiweFeprMShrW4mdB8iV2mzkiIxfA7pGDJ6j82UWYtEBPjDbhmNMkMI1IV21vr8X7FZJAkVyBE9+HflkWHTnOZ13/+pjSFyLenTZwuCN9AZbsTBiDWQrw0EFzjQhbo/stzKDBWcyxzdhseP5oQWiZ6xozpV+bLrCuxUORDVkG+x7u2Icp6cVby/xTzpiVKFDZY9buOh3EwsWbDmL9YqEIXMpT+7GBM3jzKjM4RFaAyWJiBbj3UH22eWGIeF61BvnveW2+tPnGq3lCVNF1nHLRvUX3riCkP8N6V+J4StRjZHkMtsU3eZVA2FSKSt0RQ5u45RuiiavvomikyniQgYmLNz57wjrAuLiI3616bPQ6i+FhXoJQhHsIfZoyCukdsL2UlytWm4RPXY+hLaZ2sUMUDO5W9Un2ztnVpprKR/i8tTO7Qy9XevLmVtRe0lkiuDhkJg9URp5I3RvWJbadogH5G2WhocskZhzPEDtiT9xSdR9JSshUmq44/68QbxWrCvYMf9/9M1UGa33zAMcWxhG7xRlPUGG6kPik4ZeOMKoXR2uUWO1ozII2PpbhTls8mte+WYzqjE/cnip5m8FpRIul+BfrO95ybXTzm8j6j+mr8szHx1kiTQUwypyNm7CrxnA5nYdlZRbb26GfgTqtMgzr4xSOwEJroUKMBIWThFBs8OUTzoQEXF9yK6LwVsYyqqXt8dklFWWmZN5p05BIgH1Z5Ia+Eq3R8ER5BU2XjjA4pqvf7kBe7PfEos5O15ZmfQddX+j0MyKi46+sasyy==' # 加密後的密碼,從瀏覽器或抓包工具中複製,可重複使用 TPL_password2 = '你的加密後密碼' ul = UsernameLogin(username, ua, TPL_password2) ul.login()