今天給你們帶來的是拉勾網模擬登陸,讓咱們愉快地開始吧~html
requests模塊;python
以及一些python自帶的模塊。正則表達式
安裝Python並添加到環境變量,pip安裝須要的相關模塊便可。json
先去拉勾網註冊個帳號供測試使用,而後打開拉勾網登陸頁面:api
按F12打開Chrome瀏覽器的開發者工具,並人工進行一次登陸操做以便咱們進行抓包。上面的操做結束以後,咱們能夠根據經驗,先全局搜索一下login這個關鍵詞看看能不能直接找到咱們須要的模擬登陸接口。搜索以後咱們能夠發現: 瀏覽器
顯然,這就是咱們想要找的模擬登陸請求的接口: session
請求該接口主要須要如下幾個參數:函數
'isValidate' 'username' 'password' 'request_form_verifyCode' 'submit' 'challenge'
其中,經測試後發現固定的參數爲:工具
'isValidate': 'true' 'username': 登陸用戶名明文 'request_form_verifyCode': '' 'submit': ''
request_form_verifyCode這個參數其實看着就像是用來放驗證碼的,可是拉勾網登陸通常不須要輸入驗證碼,至少我試的時候一直沒有出現驗證碼,即便掛了代理換了電腦進行"異地登陸"。因此這玩意就先無論啦,就當是個固定的常量吧。(源代碼裏其實加了有驗證碼狀況的處理,但那個接口是谷歌上搜到的,並且是不少年前的,看樣子在那以後拉勾網應該又更新過好幾波了,因此可靠性存疑。)post
言歸正傳,咱們如今只須要肯定下面兩個參數了:
'password' 'challenge'
顯然password是密碼的意思,可是抓包的時候咱們能夠發現這個參數是通過加密處理的:
查看一下initiator,看看密碼是咋算出來的:
顯然lgAjax那個js文件看起來最相關,打開搜索一下password這個關鍵詞,能夠找到:
顯然就是對密碼明文作兩次md5加密,python代碼能夠很輕鬆地實現這個加密,具體實現以下:
password = hashlib.md5(password.encode('utf-8')).hexdigest() password = 'veenike' + password + 'veenike' password = hashlib.md5(password.encode('utf-8')).hexdigest()
其中咱們能夠看到js文件第6380行定義了:
F = "veenike"
因此咱們就不須要經過打個斷點來肯定這個參數了。
最後再來看challenge這個參數,咱們嘗試全局搜索一下這個challenge的值,好比值爲:
bd89b07f5e4174c55a40557e109c9944
咱們能夠發現請求下面這個api接口就能夠得到該值:
顯然是一個關於極驗的api接口,不過無論他究竟是啥,反正經過請求這個接口來得到一個動態的challenge值就對了。而請求這個接口只須要攜帶兩個固定的params:
pt: 0 gt: 66442f2f720bfc86799932d8ad2eb6c7
以及一個能夠固定的data就ok啦:
(通過測試,發現雖然每次這個data會變,但你一直用同一個data也無所謂,即便過了好多個月仍然是有效能夠使用的,目測應該是驗證碼圖片相關的數據,不過既然同一個參數一直能夠用,就不用管它了,分析下去也是浪費時間。)
封裝一下,寫個獲取challenge參數的函數,就是:
'''得到challenge參數''' def __getChallenge(self): params = {'pt': '0', 'gt': '66442f2f720bfc86799932d8ad2eb6c7'} data = 'nLYvtlnNYdUU68IXi84sdryl9ucQ2skF5u8LBLKXarWE41fPrzcL7yxmf2fYN2XDG1CyhqjVaXyi2Q)3oBs537a1dNTMv4w)U5b23FFwHcWMk(3gtb8VHP7U0ltLOistf5IoI5Bt11GMavQSlQJ(ga)AsFh0wTLAC9yNwbdBfZExS0TT)Ojw010QuOFPQg2sj2jvTEER1LRMLHmQKR0KjWN)4Cq2o2WUzhwPy7sFFxJuCxUO)5377hbgo5tdjTOFHwgkUqZrY1lkmsPmexujXXIgpN9p2aa5OQ)iMRZ(p0zfuAnBYAEBOy6H6vSopUiWGeNg(IO(ppE7X0b6Zpul)GqoNs3nuVCdlamTyui5qKhr8fyFSgzxiYWamJ5xR8PbvM9XQLEPZnxqvL(2P3nuRwa4S8qTzbMTwN3fw)KvEXUC2iatqz4G6ExOcfcUbQtRp7I1fEgjNb7Y8DEAZwmqyBG0qUVc3moKM8KZrWLZxR14Wp8AaG3WzJ)s4z9ouViog8nAt1PI6xlPHWKazr7bH1mfpKYmz8z2k)TKYeQtG9XAjjWtab(dr5AsPjQk1njJmgAI(48Bh7pLzZwJIW93YAtExbuCHGauxyEU28ZrKrqTjlgqu7KeurQU5hu(DhlIdMkmRqI(xguC8GjkYAlXF7aOjSvDwkxLUrLEE44CBe2gGNEFn6uax6HhvcUHIRMtIq0BB5Va4i)hnTK)WzcH2jetHMn4KVgFykF8NTKpWIkt(qIhiW)V1DNlfbmQi0ZmpUbLyOnLX42cjxwFh5Rnxrq(4WsPVm(Y8Oz0WtPaniTrAE6hFrdXS8PKyyefa49QcTFDJr9nrCgv5bu1dg6m5jVvypdt7mKGRpy3DILQ)TZ0LX6OHBwl)4375P0X9QEXf6Dl4r9)0gNi(xSfT0FYLNJVzMfk)cNulnhOzjpDisiUu5oZHtAK0ue9BiFa40lwSXDmAHxm5DcCmkaK1eINzFTplJt9Gk5KcDxqJPCYhNX1gvXmLBpKRcgqXZmIWRU6nYmkF76WLImaEhN)HK4RYPiGCvUt3(23sAmuJoFyHEsmTLbq13KRWY0tUbKhJjcPlOJUHduT1aSiWalhY0GTfhTiHfAu09zqENSHxVMAxtzi8FVSSZfPP82eIOyphvu(gukLDRaARVVAB4QFfgAxPSDWjRAT28IkMd1SiPug(fuJ9M61l2PzMiNxfZ6TXCtgUvmkOHgIybDYdPM6PB4ObXbV2wQf0q939Mkm8eVNsMvNPRZ0b1oJo0AnCz1IsxFn4JfCpB8M328wtH)7ve1jOBB4KulYQlXJuI3HUCJoUU5I0V)xAZhRI)nX0cepkfkCMwOjKmIihoLXA3y2Z8p3r04s9NZc8ngBkdacFpqYtnR19EmDeMoKgay8PGQ)(zZf1hHhWXuZWXTXdyR)KDvRdlx9wjG2FhV95QAH3aG85Dxufapym)b6kWJzKFw(qmsSpvUwUDhVQN2lfeUjR27eb2JZ0WP1GkQfG4LZ1CJYrBcfTx3zLD))kwiq3ScaVbT)B1GVfXqEP68zeLs9J)xwU7NgsI(QKtNw7WpymPl(g(FmDmxzrAMarwdqdoG2)KJRX5Qjz)ke8VnU8A09PVsdEwWKtkXjMUbvB)7Z3OFFOA(2EoKwthpb(mMyiUghjLD9(JXfqGm2k4RVF8vATKIo7YGKgadiI5vwzs0EOdpChJVk5E7c3MMCiuUHm9axWXP0i0)PmW(ZxoiT0ZJvnyCCn60nwyjKHpp5nXnN2SKZS8WBliyhdc8RUqVRnZeh0pH27jiPUGXYkRiAuoKDzl8S6l3NWm6xPPQw1MbldzTqmMTUsOuoR5CBzlU)TJl2gCSRgE1j(ChpXGSUfUvuTwaGBFfKWyQWsWdSbcC2tSEF2WP4lSdgEntDioWtRFeGUNg8tlnswrkfS6JhgE7BgfC36H(X1fytovT3vuTwilxGIt2xWuD9iY1Qxf9CtgSvo7vJTWmYneAQEyOUyqwcF5e6un(GCrMa7sizPHqf)gPseC2CeCQH9anwH7ZHiLiMRznWM(mH1CJEt52ez)IeiVTaDFpy1oYhURRwGoxMU2MkqIkw4LBR59MuKpBUdS6kZWcr(GwZ7VBLE3GAsX8ndtwoLAmeifdRQIonF7L1qozAKBU7lyJM2oqYXs(7gLJZyIWmTXVskE8iAIXp)yRtajPfnTintzNxGHEKCyVZQrr0XBEvt3UtksAv9(1V2N8EBn7Hkb8VKw5u6BdFnc0dMQqgum(zQaTb(URg4(O9EmTXcQSpLTm4IRX(Pm)44ZYezGD(8BZoukh7Mhko6a1LizgNMdmizc)F9YBHLXXdwec1wK8OAnQcZt7rbVfIl6Vd3HqoQdcId8B)NiAT4YWhJM39jEYbgBVzBhunEFV8DjTVSqudgf009qrFN(xrIo(EP5Wo6fYmTd7X4NMjElvOOm(2SV00ftg7d7(oUwkCHcEvQieQSZe(lmxeuIS0UMLAJ0nlyfFvrf0wr2oTKek1wu0)p17viMriD8ONEOqY9bqsKZBhtiGxgzN3pTYlj3vYDMSbylh02H5iFn)efqRTD8s8amfw645BqAGI65uTRAeGLTTq6tAZex(Cfo4r21MQxKgkREGGhoky)3cKWA97jirImA..4f0ae6c11327e4367bff580c5b909a03039cf44f566fad8680886dd52987bd4956933bdd2376e53c282edd8a5b79e38d2d078bc9a1eb186462d24ed2bc4cba3b2eda457b80a6dd8b1394e159b1a2d72d2f500a2b2703e372ade0e97fd741d75d6f401801e1022fd8772a463a15ce646ca0d00efe04500dfddd33f46e037bdb20' res = requests.post(self.challenge_url, data=data, params=params) res_json = res.json() if res_json['status'] == 'success': challenge = res_json.get('challenge') else: raise RuntimeError('Get the param named challenge error, error info is %s...' % res_json.get('error')) return challenge
至此,咱們得到了全部請求最上面那個模擬登陸接口所需攜帶的參數:
data = { 'isValidate': 'true', 'username': username, 'password': password, 'request_form_verifyCode': '', 'submit': '', 'challenge': self.__getChallenge() }
試着請求一下:
self.login_url = 'https://passport.lagou.com/login/login.json' self.session.post(self.login_url, data=data, headers=login_headers)
能夠發現報錯:
估計是請求頭出了問題,仔細觀察一下請求這個接口的請求頭,能夠發現請求頭裏有如下兩個參數很可疑:
X-Anit-Forge-Token X-Anit-Forge-Code
在js文件裏也能夠搜到:
看來這兩個參數是必不可少的。而搜索一下相似的關鍵詞,發現:
因而咱們能夠直接請求:
https://passport.lagou.com/login/login.html
而後在返回的頁面裏用正則表達式提取就ok了:
def __getAnitForge(self): res = self.session.get(self.home_url, headers=self.headers) token = re.findall(r"window.X_Anti_Forge_Token = '(.*?)';", res.text)[0] code = re.findall(r"window.X_Anti_Forge_Code = '(.*?)';", res.text)[0] anit_forge = { 'X-Anit-Forge-Code': code, 'X-Anit-Forge-Token': token } return anit_forge
在請求登陸接口的headers裏添加一下這兩個參數:
login_headers.update(anit_forge)
能夠發現返回的數據變成了:
看完篇文章喜歡的朋友點個贊支持一下,關注我天天分享Python模擬登陸系列,下篇文章分享爬取她(他)的全部微博
All done~完整源代碼詳見我的簡介或者私信獲取相關文件。。