看了下網上有很多關于模擬登錄淘寶,但是基本都是使用scrapy、pyppeteer、selenium等庫來模擬登錄,但是目前我們還沒有講到這些庫,只講了requests庫,那我們今天就來使用requests庫模擬登錄淘寶!
講模擬登錄淘寶之前,我們來回顧一下之前用requests庫模擬登錄豆瓣和新浪微博的過程:這一類模擬登錄是比較簡單的登錄,只需要在請求登錄時將用戶名和密碼上傳驗證通過就成功了,也就是說一步到位!
而淘寶登錄就比較復雜,為什么說復雜呢?因為淘寶登錄涉及參數多且請求不止一次!我們就先來講講淘寶登錄的流程,先把流程原理搞懂,再去敲代碼,這樣大家就容易理解!
一、淘寶登錄流程
淘寶ua參數:ua(User-Agent)故名用戶代理,淘寶的ua參數加入了瀏覽器、ip、電腦、時間等信息,然后加密生成,在很多地方使用,不僅僅是登錄!
上圖是比較詳細的流程圖,從代碼層面考慮將模擬登錄淘寶分為以下四個步驟:
輸入用戶名后,瀏覽器會向淘寶(taobao.com)發起一個post的請求,判斷是否出現滑塊驗證!
用戶輸入密碼后,瀏覽器向淘寶(taobao.com)又發起一個post請求,驗證用戶名密碼是否正確,如果正確則返回一個token。
瀏覽器拿著token去阿里巴巴(alibaba.com)交換st碼!
瀏覽器獲取st碼之后,拿著st碼獲取cookies,登錄成功
這里也許有同學會提出疑問:為什么淘寶(taobao.com)驗證通過之后還要拿著 token去阿里巴巴(alibaba.com)交換st碼呢? 這個我們放后面講!
二、模擬登錄實現
上面我們只講了大概的登錄流程,這里豬哥會先詳細講解下每一步的操作,然后再貼出實現代碼!
1.判斷是否需要驗證碼
目前我們在登錄淘寶的時候,大多數情況下是不會出現滑塊驗證碼,豬哥嘗試了很多次的登錄退出也只是在中間出現過一次,那究竟是什么在控制是否需要滑塊驗證碼的呢?
從上圖可以看出,當豬哥輸入用戶名(必須是手機號)后,瀏覽器就會發起一個post請求,來驗證是否需要出現滑塊驗證碼,如果返回true,滑塊驗證碼則出現!否則不出現,一般是不會出現!
圖中我們可以看到這次post請求上傳了兩個參數:username、ua!
前面豬哥說過ua為瀏覽器、ip、設備信息等多信息加密參數,所以豬哥猜想淘寶的驗證碼是否出現不僅僅從賬號角度,還有ip、設備等角度!
舉個例子:某臺設備可能出現登錄過大量的賬號,這時候淘寶就可以從ua參數中獲取設備號,然后對該設備進行限制!
2.驗證用戶名密碼
這里一步也就是上面時序圖圖中的第5步:請求登錄,這里會將用戶名、ua參數、加密密碼等30十幾個參數post到淘寶(taobao.com)去驗證。我們來用代碼實現一下,大家別被這么多參數嚇到,都是從瀏覽器復制過來的!
可以看到申請st碼鏈接后面帶了一個token,具體token是干什么用的后面我們再分析!
3.申請st碼
上面我們已經申請到了淘寶(taobao.com)的token,這一步就是用token來換取st碼。
到這里很多人可能會有疑問:為什么淘寶登錄需要這么麻煩呢?直接在 taobao.com 登錄不就可以嗎?為什么要先在taobao驗證用戶名密碼,通過之后再去 alibaba.com 換取st碼登錄呢?
任何公司的框架都是慢慢演變的結果,我想最開始的淘寶登錄肯定沒這么復雜。但是隨著阿里巴巴的慢慢壯大,很多事業線都劃分開來,但是這些事業線之間又有關聯性,比如用戶登錄了淘寶賬號之后天貓就不需要再登錄了呢?(注意淘寶和天貓的頂級域名不同,所以不能共享cookis)為了解決這個問題,單點登錄就出現了。
單點登錄(Single Sign On),簡稱為 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,用戶只需要登錄一次就可以訪問所有相互信任的應用系統。 ――百度百科
很多大企業幾乎都有做單點登錄,那阿里的單點登錄系統肯定是由母公司阿里巴巴(alibaba.com)來做啦,所有子公司去調用母公司接口!
我們再回來分析淘寶登錄為何要如此復雜就很好理解了:用戶數據在淘寶這里,所以需要現在淘寶(taobao.com)驗證用戶名和密碼,驗證通過生成一個token,瀏覽器拿著token去和阿里巴巴(alibaba.com)申請單點登錄碼(st碼),阿里巴巴收到請求驗證token通過則返回st碼,所以用token換st碼的原因就在于單點登錄!
理解了設計原理之后,代碼實現起來就很清晰了!
4.使用st碼登錄
成功獲取st碼之后我們就可以來登錄了,這一步是通過st碼獲取登錄的cookies。
到這里我們就已經模擬登錄淘寶成功了!
5.獲取淘寶昵稱
其實上面我們就已經登錄淘寶成功并返回用戶主頁的鏈接,我們為了進一步驗證登錄成功,就請求一下淘寶用戶主頁,順便把淘寶昵稱提取出來吧!
三、總結
整體講完之后我們來稍微總結一下吧,主要從代碼結構和存在的問題兩個方面說下:
1.代碼結構
來放出一張代碼結構圖,讓大家直觀了解
這就是我們前面說過的模擬登錄淘寶的四個步驟,不過這里我們是用代碼實現了!
2.存在問題
在寫這篇教程之前也是先在網上了解,然后自己用瀏覽器和抓包工具(Charles)一步一步實踐,最重要的是你先要了解淘寶登錄的大概流程,不然你實際操作起來會一頭霧水,下面就要講講目前遇到的問題和存在的問題吧
首先第一個問題便是淘寶的滑塊解鎖,目前requests還沒有很好的破解辦法,后面介紹了一些爬蟲框架之后我們再來破解吧!
豬哥嘗試了很多次(50次以上)登錄退出都沒出現過滑塊驗證碼。
網上有人使用代理ip,這里豬哥也沒用,只要你不是超級超級超級頻繁且大量爬取數據,一般大廠都不太會去封ip,因為有誤傷率和影響用戶面太廣,也許一封就是整個小區。
在第二步驗證用戶名和密碼時,上傳了近30個參數,如果你把username、ua、加密密碼復制進去驗證還是不通過可嘗試把那30個參數換成你瀏覽器中的!
在第三步和第四步偶爾會出現一次錯誤,重試一下就可以!
看到這里是不是感覺淘寶模擬登錄就清晰明了很多了,感興趣的同學可以收藏轉發,周末有空自己嘗試一下。征服淘寶登錄,其他登錄也就相對簡單了!
下面是源碼
# -*- coding:utf-8 -*- 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 = "https://i.taobao.com/my_taobao.htm" # 淘寶用戶名 self.username = "手機號" # 淘寶關鍵參數,包含用戶瀏覽器等一些信息,很多地方會使用,從瀏覽器或抓包工具中復制,可重復使用 self.ua = "" # 加密后的密碼,從瀏覽器或抓包工具中復制,可重復使用 self.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 = { redirectURL=https%3A%2F%2Fi.taobao.com%2Fmy_taobao.htm%3Fspm%3Da2d00.7723416.754894437.1.61531fc917M0p9%26ad_id%3D%26am_id%3D%26cm_id%3D%26pm_id%3D1501036000a02c5c3739", # ":scheme": "https", "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", "accept-encoding": "gzip, deflate, br", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "max-age=0", "content-length": "2858", "content-type": "application/x-www-form-urlencoded", "sec-fetch-mode": "navigate", "sec-fetch-site": "same-origin", "sec-fetch-user": "?1", "Cache-Control": "max-age=0", "Origin": "https://login.taobao.com", "Upgrade-Insecure-Requests": "1", "User-Agent": "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded", "Referer": "https://login.taobao.com/member/login.jhtml?redirectURL=https%3A%2F%2Fi.taobao.com%2Fmy_taobao.htm%3Fspm%3Da2d00.7723416.754894437.1.61531fc917M0p9%26ad_id%3D%26am_id%3D%26cm_id%3D%26pm_id%3D1501036000a02c5c3739", } # 登錄toabao.com提交的數據,如果登錄失敗,可以從瀏覽器復制你的form data verify_password_data = { "TPL_username": self.username, "ncoToken": "1f1389fac2a670101d8a09de4c99795e8023b341", "slideCodeShow": "false", "useMobile": "false", "lang": "zh_CN", "loginsite": 0, "newlogin": 0, "TPL_redirect_url": "https://i.taobao.com/my_taobao.htm?spm=a2d00.7723416.754894437.1.61531fc917M0p9&ad_id=&am_id=&cm_id=&pm_id=1501036000a02c5c3739", "from": "tb", "fc": "default", "style": "default", "keyLogin": "false", "qrLogin": "true", "newMini": "false", "newMini2": "false", "loginType": "3", "gvfdcname": "10", # "gvfdcre": "68747470733A2F2F6C6F67696E2E74616F62616F2E636F6D2F6D656D6265722F6C6F676F75742E6A68746D6C3F73706D3D613231626F2E323031372E3735343839343433372E372E356166393131643970714B52693126663D746F70266F75743D7472756526726564697265637455524C3D68747470732533412532462532467777772E74616F62616F2E636F6D253246", "TPL_password_2": self.TPL_password2, "loginASR": "1", "loginASRSuc": "1", "oslanguage": "zh-CN", "sr": "1920*1080", # "osVer": "macos|10.145", "naviVer": "chrome|78.039047", "osACN": "Mozilla", "osAV": "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36", "osPF": "Win32", "appkey": "00000000", "mobileLoginLink": "https://login.taobao.com/member/login.jhtml?redirectURL=https://i.taobao.com/my_taobao.htm?spm=a2d00.7723416.754894437.1.61531fc917M0p9&ad_id=&am_id=&cm_id=&pm_id=1501036000a02c5c3739&useMobile=true", "showAssistantLink": "false", "um_token": "T274D86E0BEB4F2F2F527C889BADD92868CE10177BeFF895DE627CFE2D52A", "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)) # raise RuntimeError("獲取st碼失敗!") 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": "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 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("登錄失?。esponse:{}".format(response.text)) def _load_cookies(self): # 1、判斷cookies序列化文件是否存在 if not os.path.exists(COOKIES_FILE_PATH): return False # 2、加載cookies s.cookies = self._deserialization_cookies() # 3、判斷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": "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 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 = "" # 加密后的密碼,從瀏覽器或抓包工具中復制,可重復使用 TPL_password2 = "" ul = UsernameLogin(username, ua, TPL_password2) ul.login()
到此這篇關于詳解如何用Python模擬登錄淘寶的文章就介紹到這了,更多相關Python模擬登錄淘寶內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/u014044812/article/details/99584382