突破有贊後臺滑塊驗證碼實現自動登錄,內附Python代碼 | 州的先生

點擊關注州的先生

編程應用、實戰教程,不容錯過python


本文來自於【州的先生讀者交流羣】北辰劃江南的工做分享,添加微信號 taoist_ling 備註入羣,即刻加入

1、前言

背景:運營方面須要作份數據報表統計發給領導,涉及到有贊後臺數據的統計,以下圖所示:web

但是運營不想本身弄,有贊方面沒有提供相應的數據接口。因此準備用模擬登錄的方式獲取這些數據。採用Python3+selenium3實現,本人作PHP程序開發的,python小白一個,大牛請略過此文。chrome

2、破解

登錄入口:

https://account.youzan.com/login編程

點擊登錄:

selenium能夠實現對網頁元素的定位,經過谷歌瀏覽器開發者工具獲取。我是經過xpath獲取的,以下圖所示:瀏覽器

鼠標右鍵單擊選中Copy→Copy XPath,經過findelementby_xpath方法獲取,部分代碼以下圖所示:微信

滑塊驗證

通過屢次嘗試,發現有贊後臺登錄的滑塊「缺口」部分的位置基本上都在靠右側的一面,並且每次須要拖動的距離都有必定範圍。因此只須要設置大概的滑動範圍,失敗的時候能夠經過增減移動距離進行重試便可。網絡

模擬拖動

經過谷歌開發者工具能夠看到拖動滑塊實際上是經過iframe加載進來的,先獲取其xpath:app

再經過switch_to方法切換frame,經過selenium.webdriver的ActionChains類實現拖動操做部分代碼以下所示:工具

構造移動軌跡

模仿人的滑動行爲,先勻加速後勻減速,具體實現代碼以下:flex

驗證成功

經過對滑動驗證的提示信息能夠得知驗證是否成功。以下圖所示:

經過findelementbyclassname('tcaptcha-title').text來判斷驗證是否成功。

失敗重試

經過設置一個初始距離移動滑塊,移動的距離過長的話則減少距離重試滑動,因此須要經過循環處理。具體代碼以下:

   
     
   
   
    
    
             
    
    









# coding=utf-8from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver import ActionChains # 滑動驗證碼from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0from time import sleepurl = "https://account.youzan.com/login"# 登陸名和密碼username = xxxxx passwd = "xxxx"# 滑動破解之模擬構造移動軌跡def get_track(distance): ''' 拿到移動軌跡,模仿人的滑動行爲,先勻加速後勻減速 勻變速運動基本公式: ①v=v0+at ②s=v0t+½at² ③v²-v0²=2as :param distance: 須要移動的距離 :return: 存放每0.3秒移動的距離 ''' v = 0 # 初速度 t = 0.3 # 單位時間爲0.2s來統計軌跡,軌跡即0.2內的位移 tracks = [] # 位移/軌跡列表,列表內的一個元素表明0.2s的位移 current = 0 # 當前的位移 mid = distance * 4 / 5 # 到達mid值開始減速 while current < distance: if current < mid: a = 2 # 加速度越小,單位時間的位移越小,模擬的軌跡就越多越詳細 else: a = -3 v0 = v # 初速度 s = v0 * t + 0.5 * a * (t ** 2) # 0.2秒時間內的位移 current += s # 當前的位置 tracks.append(round(s)) # 添加到軌跡列表 v = v0 + a * t # 速度已經達到v,該速度做爲下次的初速度 return tracksdef main(): driver = webdriver.Chrome(executable_path=r"D:\softwares\chromedriver\chromedriver.exe") driver.set_window_position(900, 10) driver.get(url) sleep(1) # 輸入用戶名和密碼 driver.find_element_by_xpath('//*[@id="app"]/div/div[2]/div[1]/div/div[2]/div/form/div[1]/div/div/input').clear() driver.find_element_by_xpath('//*[@id="app"]/div/div[2]/div[1]/div/div[2]/div/form/div[1]/div/div/input').send_keys(username) driver.find_element_by_xpath('//*[@id="app"]/div/div[2]/div[1]/div/div[2]/div/form/div[2]/div/div/input').clear() driver.find_element_by_xpath('//*[@id="app"]/div/div[2]/div[1]/div/div[2]/div/form/div[2]/div/div/input').send_keys(passwd) sleep(1) # 點擊登陸 driver.find_element_by_xpath('//*[@id="app"]/div/div[2]/div[1]/div/div[2]/div/form/div[3]/div[2]/button').click() # 檢測id爲"TCaptcha"的元素是否加在DOM樹中,若是出現了才能正常向下執行 element = WebDriverWait(driver, 5, 0.5).until( EC.presence_of_element_located((By.ID, "TCaptcha")) ) element.click() sleep(5) # 切換iframe try: iframe = driver.find_element_by_xpath('//*[@id="TCaptcha"]/iframe') except Exception as e: pass sleep(2) # 等待資源加載 driver.switch_to.frame(iframe) # 等待圖片加載出來 WebDriverWait(driver, 5, 0.5).until( EC.presence_of_element_located((By.ID, "tcaptcha_drag_button")) ) try: button = driver.find_element_by_id('tcaptcha_drag_button') # 找到藍色滑塊 except Exception as e: pass sleep(1) # 開始拖動 perform()用來執行ActionChains中存儲的行爲 flag = 0 distance = 185 offset = 5 times = 0 while 1: action = ActionChains(driver) action.click_and_hold(button).perform() action.reset_actions() # 清除以前的action print(distance) track = get_track(distance) for i in track: action.move_by_offset(xoffset=i, yoffset=0).perform() action.reset_actions() sleep(0.5) action.release().perform() sleep(5) try: alert = driver.find_element_by_class_name('tcaptcha-title').text except Exception as e: pass alert = '' if alert: print(u'滑塊位移須要調整: %s' % alert) distance -= offset times += 1 sleep(5) else: print('滑塊驗證經過') flag = 1 driver.switch_to.parent_frame() # 驗證成功後跳回最外層頁面 break sleep(2) driver.quit() print("success~~") return flagif __name__ == '__main__': main()

3、小結

須要注意一點是,因爲受到網絡環境影響,有時候加載網頁信息比較慢,因此要在程序中加判斷條件。還有在屢次滑動失敗後,會彈出輸入驗證碼,這塊驗證暫時還沒處理。網上還找到一種經過OpenCV識別缺口位置滑動登錄的方式。還有其餘的能夠看知乎這裏大牛的解決思路:https://www.zhihu.com/question/32209043

有什麼好的想法?歡迎留言討論~


微信大改版

你就快找不到【州的先生】了...


快來星標 / 置頂「州的先生」

 ⭐ 不在信息狂流中錯失好內容  ⭐


萬水千山老是情,點個「好看」行不行↓↓↓

本文分享自微信公衆號 - 州的先生(zmister2016)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索