詳解如何用Python模擬登錄淘寶
看了下網(wǎng)上有很多關(guān)于模擬登錄淘寶,但是基本都是使用scrapy、pyppeteer、selenium等庫(kù)來(lái)模擬登錄,但是目前我們還沒(méi)有講到這些庫(kù),只講了requests庫(kù),那我們今天就來(lái)使用requests庫(kù)模擬登錄淘寶!
講模擬登錄淘寶之前,我們來(lái)回顧一下之前用requests庫(kù)模擬登錄豆瓣和新浪微博的過(guò)程:這一類(lèi)模擬登錄是比較簡(jiǎn)單的登錄,只需要在請(qǐng)求登錄時(shí)將用戶(hù)名和密碼上傳驗(yàn)證通過(guò)就成功了,也就是說(shuō)一步到位!
而淘寶登錄就比較復(fù)雜,為什么說(shuō)復(fù)雜呢?因?yàn)樘詫毜卿浬婕皡?shù)多且請(qǐng)求不止一次!我們就先來(lái)講講淘寶登錄的流程,先把流程原理搞懂,再去敲代碼,這樣大家就容易理解!
一、淘寶登錄流程
淘寶ua參數(shù):ua(User-Agent)故名用戶(hù)代理,淘寶的ua參數(shù)加入了瀏覽器、ip、電腦、時(shí)間等信息,然后加密生成,在很多地方使用,不僅僅是登錄!
上圖是比較詳細(xì)的流程圖,從代碼層面考慮將模擬登錄淘寶分為以下四個(gè)步驟:
輸入用戶(hù)名后,瀏覽器會(huì)向淘寶(taobao.com)發(fā)起一個(gè)post的請(qǐng)求,判斷是否出現(xiàn)滑塊驗(yàn)證!
用戶(hù)輸入密碼后,瀏覽器向淘寶(taobao.com)又發(fā)起一個(gè)post請(qǐng)求,驗(yàn)證用戶(hù)名密碼是否正確,如果正確則返回一個(gè)token。
瀏覽器拿著token去阿里巴巴(alibaba.com)交換st碼!
瀏覽器獲取st碼之后,拿著st碼獲取cookies,登錄成功
這里也許有同學(xué)會(huì)提出疑問(wèn):為什么淘寶(taobao.com)驗(yàn)證通過(guò)之后還要拿著 token去阿里巴巴(alibaba.com)交換st碼呢? 這個(gè)我們放后面講!
二、模擬登錄實(shí)現(xiàn)
上面我們只講了大概的登錄流程,這里豬哥會(huì)先詳細(xì)講解下每一步的操作,然后再貼出實(shí)現(xiàn)代碼!
1.判斷是否需要驗(yàn)證碼
目前我們?cè)诘卿浱詫毜臅r(shí)候,大多數(shù)情況下是不會(huì)出現(xiàn)滑塊驗(yàn)證碼,豬哥嘗試了很多次的登錄退出也只是在中間出現(xiàn)過(guò)一次,那究竟是什么在控制是否需要滑塊驗(yàn)證碼的呢?
從上圖可以看出,當(dāng)豬哥輸入用戶(hù)名(必須是手機(jī)號(hào))后,瀏覽器就會(huì)發(fā)起一個(gè)post請(qǐng)求,來(lái)驗(yàn)證是否需要出現(xiàn)滑塊驗(yàn)證碼,如果返回true,滑塊驗(yàn)證碼則出現(xiàn)!否則不出現(xiàn),一般是不會(huì)出現(xiàn)!
圖中我們可以看到這次post請(qǐng)求上傳了兩個(gè)參數(shù):username、ua!
前面豬哥說(shuō)過(guò)ua為瀏覽器、ip、設(shè)備信息等多信息加密參數(shù),所以豬哥猜想淘寶的驗(yàn)證碼是否出現(xiàn)不僅僅從賬號(hào)角度,還有ip、設(shè)備等角度!
舉個(gè)例子:某臺(tái)設(shè)備可能出現(xiàn)登錄過(guò)大量的賬號(hào),這時(shí)候淘寶就可以從ua參數(shù)中獲取設(shè)備號(hào),然后對(duì)該設(shè)備進(jìn)行限制!
2.驗(yàn)證用戶(hù)名密碼
這里一步也就是上面時(shí)序圖圖中的第5步:請(qǐng)求登錄,這里會(huì)將用戶(hù)名、ua參數(shù)、加密密碼等30十幾個(gè)參數(shù)post到淘寶(taobao.com)去驗(yàn)證。我們來(lái)用代碼實(shí)現(xiàn)一下,大家別被這么多參數(shù)嚇到,都是從瀏覽器復(fù)制過(guò)來(lái)的!
可以看到申請(qǐng)st碼鏈接后面帶了一個(gè)token,具體token是干什么用的后面我們?cè)俜治觯?/p>
3.申請(qǐng)st碼
上面我們已經(jīng)申請(qǐng)到了淘寶(taobao.com)的token,這一步就是用token來(lái)?yè)Q取st碼。
到這里很多人可能會(huì)有疑問(wèn):為什么淘寶登錄需要這么麻煩呢?直接在 taobao.com 登錄不就可以嗎?為什么要先在taobao驗(yàn)證用戶(hù)名密碼,通過(guò)之后再去 alibaba.com 換取st碼登錄呢?
任何公司的框架都是慢慢演變的結(jié)果,我想最開(kāi)始的淘寶登錄肯定沒(méi)這么復(fù)雜。但是隨著阿里巴巴的慢慢壯大,很多事業(yè)線都劃分開(kāi)來(lái),但是這些事業(yè)線之間又有關(guān)聯(lián)性,比如用戶(hù)登錄了淘寶賬號(hào)之后天貓就不需要再登錄了呢?(注意淘寶和天貓的頂級(jí)域名不同,所以不能共享cookis)為了解決這個(gè)問(wèn)題,單點(diǎn)登錄就出現(xiàn)了。
單點(diǎn)登錄(Single Sign On),簡(jiǎn)稱(chēng)為 SSO,是目前比較流行的企業(yè)業(yè)務(wù)整合的解決方案之一。SSO的定義是在多個(gè)應(yīng)用系統(tǒng)中,用戶(hù)只需要登錄一次就可以訪問(wèn)所有相互信任的應(yīng)用系統(tǒng)。 ——百度百科
很多大企業(yè)幾乎都有做單點(diǎn)登錄,那阿里的單點(diǎn)登錄系統(tǒng)肯定是由母公司阿里巴巴(alibaba.com)來(lái)做啦,所有子公司去調(diào)用母公司接口!
我們?cè)倩貋?lái)分析淘寶登錄為何要如此復(fù)雜就很好理解了:用戶(hù)數(shù)據(jù)在淘寶這里,所以需要現(xiàn)在淘寶(taobao.com)驗(yàn)證用戶(hù)名和密碼,驗(yàn)證通過(guò)生成一個(gè)token,瀏覽器拿著token去和阿里巴巴(alibaba.com)申請(qǐng)單點(diǎn)登錄碼(st碼),阿里巴巴收到請(qǐng)求驗(yàn)證token通過(guò)則返回st碼,所以用token換st碼的原因就在于單點(diǎn)登錄!
理解了設(shè)計(jì)原理之后,代碼實(shí)現(xiàn)起來(lái)就很清晰了!
4.使用st碼登錄
成功獲取st碼之后我們就可以來(lái)登錄了,這一步是通過(guò)st碼獲取登錄的cookies。
到這里我們就已經(jīng)模擬登錄淘寶成功了!
5.獲取淘寶昵稱(chēng)
其實(shí)上面我們就已經(jīng)登錄淘寶成功并返回用戶(hù)主頁(yè)的鏈接,我們?yōu)榱诉M(jìn)一步驗(yàn)證登錄成功,就請(qǐng)求一下淘寶用戶(hù)主頁(yè),順便把淘寶昵稱(chēng)提取出來(lái)吧!
三、總結(jié)
整體講完之后我們來(lái)稍微總結(jié)一下吧,主要從代碼結(jié)構(gòu)和存在的問(wèn)題兩個(gè)方面說(shuō)下:
1.代碼結(jié)構(gòu)
來(lái)放出一張代碼結(jié)構(gòu)圖,讓大家直觀了解
這就是我們前面說(shuō)過(guò)的模擬登錄淘寶的四個(gè)步驟,不過(guò)這里我們是用代碼實(shí)現(xiàn)了!
2.存在問(wèn)題
在寫(xiě)這篇教程之前也是先在網(wǎng)上了解,然后自己用瀏覽器和抓包工具(Charles)一步一步實(shí)踐,最重要的是你先要了解淘寶登錄的大概流程,不然你實(shí)際操作起來(lái)會(huì)一頭霧水,下面就要講講目前遇到的問(wèn)題和存在的問(wèn)題吧
首先第一個(gè)問(wèn)題便是淘寶的滑塊解鎖,目前requests還沒(méi)有很好的破解辦法,后面介紹了一些爬蟲(chóng)框架之后我們?cè)賮?lái)破解吧!
豬哥嘗試了很多次(50次以上)登錄退出都沒(méi)出現(xiàn)過(guò)滑塊驗(yàn)證碼。
網(wǎng)上有人使用代理ip,這里豬哥也沒(méi)用,只要你不是超級(jí)超級(jí)超級(jí)頻繁且大量爬取數(shù)據(jù),一般大廠都不太會(huì)去封ip,因?yàn)橛姓`傷率和影響用戶(hù)面太廣,也許一封就是整個(gè)小區(qū)。
在第二步驗(yàn)證用戶(hù)名和密碼時(shí),上傳了近30個(gè)參數(shù),如果你把username、ua、加密密碼復(fù)制進(jìn)去驗(yàn)證還是不通過(guò)可嘗試把那30個(gè)參數(shù)換成你瀏覽器中的!
在第三步和第四步偶爾會(huì)出現(xiàn)一次錯(cuò)誤,重試一下就可以!
看到這里是不是感覺(jué)淘寶模擬登錄就清晰明了很多了,感興趣的同學(xué)可以收藏轉(zhuǎn)發(fā),周末有空自己嘗試一下。征服淘寶登錄,其他登錄也就相對(duì)簡(jiǎn)單了!
下面是源碼
# -*- 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): """ 賬號(hào)登錄對(duì)象 :param username: 用戶(hù)名 :param ua: 淘寶的ua參數(shù) :param TPL_password2: 加密后的密碼 """ # 檢測(cè)是否需要驗(yàn)證碼的URL self.user_check_url = 'https://login.taobao.com/member/request_nick_check.do?_input_charset=utf-8' # 驗(yàn)證淘寶用戶(hù)名密碼URL self.verify_password_url = "https://login.taobao.com/member/login.jhtml" # 訪問(wèn)st碼URL self.vst_url = 'https://login.taobao.com/member/vst.htm?st={}' # 淘寶個(gè)人 主頁(yè) self.my_taobao_url = 'https://i.taobao.com/my_taobao.htm' # 淘寶用戶(hù)名 self.username = "手機(jī)號(hào)" # 淘寶關(guān)鍵參數(shù),包含用戶(hù)瀏覽器等一些信息,很多地方會(huì)使用,從瀏覽器或抓包工具中復(fù)制,可重復(fù)使用 self.ua = "" # 加密后的密碼,從瀏覽器或抓包工具中復(fù)制,可重復(fù)使用 self.TPL_password2 = "" # 請(qǐng)求超時(shí)時(shí)間 self.timeout = 3 def _user_check(self): """ 檢測(cè)賬號(hào)是否需要驗(yàn)證碼 :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('檢測(cè)是否需要驗(yàn)證碼請(qǐng)求失敗,原因:') raise e needcode = response.json()['needcode'] print('是否需要滑塊驗(yàn)證:{}'.format(needcode)) return needcode def _verify_password(self): """ 驗(yàn)證用戶(hù)名密碼,并獲取st碼申請(qǐng)URL :return: 驗(yàn)證成功返回st碼申請(qǐng)地址 """ 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提交的數(shù)據(jù),如果登錄失敗,可以從瀏覽器復(fù)制你的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() # 從返回的頁(yè)面中提取申請(qǐng)st碼地址 except Exception as e: print('驗(yàn)證用戶(hù)名和密碼請(qǐng)求失敗,原因:') raise e # 提取申請(qǐng)st碼url apply_st_url_match = re.search(r'<script src="(.*?)"></script>', response.text) # 存在則返回 if apply_st_url_match: print('驗(yàn)證用戶(hù)名密碼成功,st碼申請(qǐng)地址:{}'.format(apply_st_url_match.group(1))) return apply_st_url_match.group(1) else: raise RuntimeError('用戶(hù)名密碼驗(yàn)證失?。esponse:{}'.format(response.text)) def _apply_st(self): """ 申請(qǐng)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('申請(qǐng)st碼請(qǐng)求失敗,原因:') 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碼失?。esponse:{}'.format(response.text)) # raise RuntimeError('獲取st碼失?。?) def login(self): """ 使用st碼登錄 :return: """ # 加載cookies文件 if self._load_cookies(): return True # 判斷是否需要滑塊驗(yàn)證 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碼登錄請(qǐng)求,原因:') raise e # 登錄成功,提取跳轉(zhuǎn)淘寶用戶(hù)主頁(yè)url my_taobao_match = re.search(r'top.location.href = "(.*?)"', response.text) if my_taobao_match: print('登錄淘寶成功,跳轉(zhuǎn)鏈接:{}'.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是否過(guò)期 try: self.get_taobao_nick_name() except Exception as e: os.remove(COOKIES_FILE_PATH) print('cookies過(guò)期,刪除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): """ 獲取淘寶昵稱(chēng) :return: 淘寶昵稱(chēng) """ 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('獲取淘寶主頁(yè)請(qǐng)求失敗!原因:') raise e # 提取淘寶昵稱(chēng) nick_name_match = re.search(r'<input id="mtb-nickname" type="hidden" value="(.*?)"/>', response.text) if nick_name_match: print('登錄淘寶成功,你的用戶(hù)名是:{}'.format(nick_name_match.group(1))) return nick_name_match.group(1) else: raise RuntimeError('獲取淘寶昵稱(chēng)失??!response:{}'.format(response.text)) if __name__ == '__main__': # 淘寶用戶(hù)名 username = '手機(jī)號(hào)' # 淘寶重要參數(shù),從瀏覽器或抓包工具中復(fù)制,可重復(fù)使用 ua = '' # 加密后的密碼,從瀏覽器或抓包工具中復(fù)制,可重復(fù)使用 TPL_password2 = '' ul = UsernameLogin(username, ua, TPL_password2) ul.login()
到此這篇關(guān)于詳解如何用Python模擬登錄淘寶的文章就介紹到這了,更多相關(guān)Python模擬登錄淘寶內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。