python爬蟲之驗(yàn)證碼篇3-滑動驗(yàn)證碼識別技術(shù)
滑動驗(yàn)證碼介紹
本篇涉及到的驗(yàn)證碼為滑動驗(yàn)證碼,不同于極驗(yàn)證,本驗(yàn)證碼難度略低,需要的將滑塊拖動到矩形區(qū)域右側(cè)即可完成。
這類驗(yàn)證碼不常見了,官方介紹地址為:https://promotion.aliyun.com/ntms/act/captchaIntroAndDemo.html
使用起來肯定是非常安全的了,不是很好通過機(jī)器檢測
如何判斷驗(yàn)證碼類型
這個驗(yàn)證碼的標(biāo)識一般比較明顯,在頁面源碼中一般存在一個 nc.js 基本可以判定是阿里云的驗(yàn)證碼了
<script type="text/javascript" src="http://g.alicdn.com/sd/ncpc/nc.js?t=1552906749855"></script>
識別套路
截止到2019年3月18日,本驗(yàn)證碼加入了大量的selenium關(guān)鍵字驗(yàn)證,所以單純的模擬拖拽被反爬的概率滿高的,你也知道一般情況爬蟲具備時效性 不確保這種手段過一段時間還可以使用!
導(dǎo)入selenium必備的一些模塊與方法 from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait # from selenium.webdriver.support import expected_conditions as EC # from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options from selenium.webdriver import ActionChains import time import random
在啟動selenium之前必須要設(shè)置一個本機(jī)的代理,進(jìn)行基本的反[反爬] 處理,很多爬蟲在獲取用戶指紋的時候,都比較喜歡selenium,因?yàn)槭褂胹elenium模擬瀏覽器進(jìn)行數(shù)據(jù)抓取,能夠繞過客戶JS加密,繞過爬蟲檢測,繞過簽名機(jī)制
但是selenium越來越多的被各種網(wǎng)站進(jìn)行了相關(guān)屏蔽,因?yàn)閟elenium在運(yùn)行的時候會暴露出一些預(yù)定義的Javascript變量(特征字符串),例如"window.navigator.webdriver
",在非selenium環(huán)境下其值為undefined,而在selenium環(huán)境下,其值為true
下圖所示為selenium驅(qū)動下Chrome控制臺打印出的值
細(xì)致的繞過去的方法,可能需要單獨(dú)的一篇博客進(jìn)行贅述了,這里我只對上面的參數(shù)進(jìn)行屏蔽,使用到的是之前博客中涉及的mitmdump進(jìn)行代理
https://docs.mitmproxy.org/stable/concepts-certificates/
mitmdump進(jìn)行代理
技術(shù)參考來源:https://zhuanlan.zhihu.com/p/43581988
關(guān)于這個模塊的基本使用,參考我前面的博客即可,這里核心使用了如下代碼
indject_js_proxy.py from mitmproxy import ctx injected_javascript = ''' // overwrite the `languages` property to use a custom getter Object.defineProperty(navigator, "languages", { get: function() { return ["zh-CN","zh","zh-TW","en-US","en"]; } }); // Overwrite the `plugins` property to use a custom getter. Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5], }); // Pass the Webdriver test Object.defineProperty(navigator, 'webdriver', { get: () => false, }); // Pass the Chrome Test. // We can mock this in as much depth as we need for the test. window.navigator.chrome = { runtime: {}, // etc. }; // Pass the Permissions Test. const originalQuery = window.navigator.permissions.query; window.navigator.permissions.query = (parameters) => ( parameters.name === 'notifications' ? Promise.resolve({ state: Notification.permission }) : originalQuery(parameters) ); ''' def response(flow): # Only process 200 responses of HTML content. if not flow.response.status_code == 200: return # Inject a script tag containing the JavaScript. html = flow.response.text html = html.replace('<head>', '<head><script>%s</script>' % injected_javascript) flow.response.text = str(html) ctx.log.info('>>>> js代碼插入成功 <<<<') # 只要url鏈接以target開頭,則將網(wǎng)頁內(nèi)容替換為目前網(wǎng)址 # target = 'https://target-url.com' # if flow.url.startswith(target): # flow.response.text = flow.url
上述腳本放置任意目錄,之后進(jìn)行mitmdump的啟動即可
C:\user>mitmdump -s indject_js_proxy.py
Loading script indject_js_proxy.py
Proxy server listening at http://*:8080
啟動之后,通過webdriver訪問
測試網(wǎng)站:https://intoli.com/blog/not-possible-to-block-chrome-headless/chrome-headless-test.html
如果webDriver是綠色,也說明代理起作用了
selenium爬取
接下來就是通過selenium進(jìn)行一些模擬行為的操作了,這部分代碼比較簡單,編寫的時候參考一下注釋即可。
# 實(shí)例化一個啟動參數(shù)對象 chrome_options = Options() # 添加啟動參數(shù) chrome_options.add_argument('--proxy-server=127.0.0.1:8080') # 將參數(shù)對象傳入Chrome,則啟動了一個設(shè)置了窗口大小的Chrome driver = webdriver.Chrome(chrome_options=chrome_options)
關(guān)鍵函數(shù)
def move_to_gap(tracks): driver.get("https://passport.zcool.com.cn/regPhone.do?appId=1006&cback=https://my.zcool.com.cn/focus/activity") # 找到滑塊span need_move_span = driver.find_element_by_xpath('//*[@id="nc_1_n1t"]/span') # 模擬按住鼠標(biāo)左鍵 ActionChains(driver).click_and_hold(need_move_span).perform() for x in tracks: # 模擬人的拖動軌跡 print(x) ActionChains(driver).move_by_offset(xoffset=x,yoffset=random.randint(1,3)).perform() time.sleep(1) ActionChains(driver).release().perform() # 釋放左鍵
注意看到上述代碼中有何核心的點(diǎn) --- 拖拽距離的 列表tracks
if __name__ == '__main__': move_to_gap(get_track(295))
這個地方可以借鑒網(wǎng)上的方案即可
def get_track(distance): ''' 拿到移動軌跡,模仿人的滑動行為,先勻加速后勻減速 勻變速運(yùn)動基本公式: ①v=v0+at ②s=v0t+(1/2)at² ③v²-v0²=2as :param distance: 需要移動的距離 :return: 存放每0.2秒移動的距離 ''' # 初速度 v=0 # 單位時間為0.2s來統(tǒng)計(jì)軌跡,軌跡即0.2內(nèi)的位移 t=0.1 # 位移/軌跡列表,列表內(nèi)的一個元素代表0.2s的位移 tracks=[] # 當(dāng)前的位移 current=0 # 到達(dá)mid值開始減速 mid=distance * 4/5 distance += 10 # 先滑過一點(diǎn),最后再反著滑動回來 while current < distance: if current < mid: # 加速度越小,單位時間的位移越小,模擬的軌跡就越多越詳細(xì) a = 2 # 加速運(yùn)動 else: a = -3 # 減速運(yùn)動 # 初速度 v0 = v # 0.2秒時間內(nèi)的位移 s = v0*t+0.5*a*(t**2) # 當(dāng)前的位置 current += s # 添加到軌跡列表 tracks.append(round(s)) # 速度已經(jīng)達(dá)到v,該速度作為下次的初速度 v= v0+a*t # 反著滑動到大概準(zhǔn)確位置 for i in range(3): tracks.append(-2) for i in range(4): tracks.append(-1) return tracks
代碼注釋已經(jīng)添加好,可以自行查閱,臨摹一下即可明白
最后開始進(jìn)行嘗試,實(shí)測中,發(fā)現(xiàn)可以自動拖動,但是,出現(xiàn)一個問題是最后被識別為機(jī)器,這個地方,我進(jìn)行了多次的修改與調(diào)整,最終從代碼層面發(fā)現(xiàn)實(shí)現(xiàn)確實(shí)有些復(fù)雜,所以改變策略,找一下chromedriver.exe是否有修改過的版本,中間去除了selenium的一些關(guān)鍵字,運(yùn)氣不錯,被我找到了。
目前只有windows10版本和linux16.04版本
gitee地址:https://gitee.com/bobozhangyx/java-crawler/tree/master/file/%E7%BC%96%E8%AF%91%E5%90%8E%E7%9A%84chromedriver
下載之后,替換你的 chromedriver.exe
再次運(yùn)行,成功驗(yàn)證
總結(jié)
以上所述是小編給大家介紹的python爬蟲之驗(yàn)證碼篇3-滑動驗(yàn)證碼識別技術(shù),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
相關(guān)文章
Python實(shí)現(xiàn)獲取某天是某個月中的第幾周
這篇文章主要介紹了Python實(shí)現(xiàn)獲取某天是某個月中的第幾周,本文代碼實(shí)現(xiàn)獲取指定的某天是某個月中的第幾周、周一作為一周的開始,需要的朋友可以參考下2015-02-02Python+Opencv實(shí)現(xiàn)表格邊框線檢測
Python數(shù)據(jù)開發(fā)工作時偶爾會要求對圖片做邊框線檢查和圖片中的直線,本文為大家整理了相關(guān)的實(shí)現(xiàn)方法,非常實(shí)用,建議有需要的小伙伴收藏一下2023-05-05Pycharm無法使用已經(jīng)安裝Selenium的解決方法
今天小編就為大家分享一篇Pycharm無法使用已經(jīng)安裝Selenium的解決方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10Python模擬登陸網(wǎng)頁的三種方法小結(jié)
如何使用Python模擬登陸網(wǎng)頁,尤其是在涉及到復(fù)雜的認(rèn)證機(jī)制時?這篇文章將詳細(xì)介紹Python模擬登陸網(wǎng)頁的三種方法,以及如何繞過一些常見的安全防護(hù)措施,需要的朋友可以參考下2024-01-01Python實(shí)現(xiàn)聊天機(jī)器人的示例代碼
這篇文章主要介紹了Python實(shí)現(xiàn)聊天機(jī)器人,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07