使用Python + Selenium破解滑塊驗(yàn)證碼

在前面一篇博客贬派,介紹了 Selenium 的基本用法和爬蟲開發(fā)過(guò)程中經(jīng)常使用的一些小技巧彻桃,利用這些寫出一個(gè)瀏覽器爬蟲已經(jīng)完全沒(méi)有問(wèn)題了坛善。看了前一篇博客邻眷,可能有人會(huì)有疑惑眠屎,瀏覽器爬蟲的優(yōu)勢(shì)感覺(jué)并不比傳統(tǒng)爬蟲多多少啊,特別是通過(guò)遍歷頁(yè)面元素來(lái)獲取爬蟲數(shù)據(jù)的方式和傳統(tǒng)爬蟲解析 HTML 文檔結(jié)構(gòu)的方式如出一轍耗溜。為了體現(xiàn)瀏覽器爬蟲的優(yōu)越性,我特意準(zhǔn)備了這篇博客省容,來(lái)看看如果要破解滑塊驗(yàn)證碼抖拴,瀏覽器爬蟲比傳統(tǒng)爬蟲要容易多少。

一腥椒、滑塊驗(yàn)證碼簡(jiǎn)述

有爬蟲阿宅,自然就有反爬蟲,就像病毒和殺毒軟件一樣笼蛛,有攻就有防洒放,兩者彼此推進(jìn)發(fā)展。反爬技術(shù)歷經(jīng)多年滨砍,從最簡(jiǎn)單的檢測(cè) UserAgent 或者 Referrer 等頭部往湿,到限制訪問(wèn)頻率封 IP 等手段,到關(guān)鍵路徑的行為識(shí)別惋戏,到前端頁(yè)面的混淆和加密领追,到目前最流行的驗(yàn)證碼技術(shù),可以說(shuō)响逢,為了防止網(wǎng)絡(luò)上大量爬蟲的肆意妄為绒窑,特別是一些垃圾機(jī)器人,技術(shù)人員真的是絞盡腦汁舔亭。但是道高一尺魔高一丈些膨,直到目前為止蟀俊,也并沒(méi)有完全無(wú)懈可擊的反爬方案。

目前最流行的反爬技術(shù)是驗(yàn)證碼订雾,幾乎所有網(wǎng)站的注冊(cè)頁(yè)面都會(huì)用到驗(yàn)證碼技術(shù)肢预,為了防止爬蟲自動(dòng)注冊(cè),批量生成垃圾賬號(hào)葬燎。驗(yàn)證碼技術(shù)從一誕生误甚,就是黑客們最感興趣的話題,驗(yàn)證碼的英文為 CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart)谱净,翻譯成中文就是 全自動(dòng)區(qū)分計(jì)算機(jī)和人類的公開圖靈測(cè)試窑邦,它是一種可以區(qū)分用戶是計(jì)算機(jī)還是人的測(cè)試,只要能通過(guò) CAPTCHA 測(cè)試壕探,該用戶就可以被認(rèn)為是人類冈钦。使用計(jì)算機(jī)模擬人類的行為一直以來(lái)都是黑客們最熱衷的事情,也是黑客們夢(mèng)寐以求的理想李请。所以驗(yàn)證碼技術(shù)從一提出瞧筛,就有大量的人嘗試破解,其實(shí)這些人并不是為了制造垃圾爬蟲导盅,他們只是相信計(jì)算機(jī)可以和人一樣较幌,阿西莫夫的機(jī)器人世界在未來(lái)是可能的。

最初的驗(yàn)證碼只是一張圖片白翻,圖片上顯示扭曲變形的文字和數(shù)字乍炉,這樣的驗(yàn)證碼通過(guò)圖像處理和識(shí)別的技術(shù)可以達(dá)到很高的識(shí)別率。后來(lái)驗(yàn)證碼技術(shù)又在圖片上加入了各種干擾項(xiàng)滤馍,并且將字符粘連在一起岛琼,增加了字符切割和識(shí)別的難度,但是很快人們就想出了很多種不同的去噪方法巢株,并使用骨架算法切割粘連字符槐瑞,還有些人提出使用機(jī)器學(xué)習(xí)算法來(lái)切割字符。和圖片驗(yàn)證碼類似的是語(yǔ)音驗(yàn)證碼阁苞,不過(guò)這種驗(yàn)證碼只是在表現(xiàn)形式上有所區(qū)別困檩,實(shí)質(zhì)上和圖片并沒(méi)有太大的變化,采用語(yǔ)音識(shí)別技術(shù)破解也不是難事那槽。而且語(yǔ)音和圖片比起來(lái)缺乏交互窗看,花樣要少很多,識(shí)別難度也要低一些倦炒,所以只有在給盲人或者對(duì)顏色分辨有障礙的人提供服務(wù)時(shí)才可能會(huì)使用語(yǔ)音驗(yàn)證碼显沈,一般情況下使用的比較少。在靜態(tài)的圖片驗(yàn)證碼被破解之后,又出現(xiàn)了動(dòng)態(tài)的圖片驗(yàn)證碼拉讯,將字符動(dòng)態(tài)的顯示在 gif 動(dòng)畫上涤浇,不過(guò)這也沒(méi)什么用,通過(guò)圖像識(shí)別技術(shù)一樣可以破解魔慷,實(shí)在破解不了的只锭,還可以通過(guò)網(wǎng)上一些廉價(jià)的打碼平臺(tái)來(lái)人肉識(shí)別。

打碼平臺(tái)的誕生可以說(shuō)是驗(yàn)證碼領(lǐng)域的一件大事院尔,它雖然不是什么高科技蜻展,只是把全世界廉價(jià)的勞動(dòng)力匯集在了一起,就這樣邀摆,再?gòu)?fù)雜的驗(yàn)證碼都不在話下纵顾。這雖然不是什么光榮的事,但是它推動(dòng)了驗(yàn)證碼技術(shù)的發(fā)展栋盹,交互式驗(yàn)證碼被開發(fā)出來(lái)施逾。傳統(tǒng)的圖片驗(yàn)證碼采用一問(wèn)一答的形式,只要答案正確例获,就認(rèn)為驗(yàn)證通過(guò)汉额,它并不關(guān)心答案是怎么來(lái)的,所以出現(xiàn)了一些人工打碼平臺(tái)榨汤,你提供一個(gè)問(wèn)題蠕搜,它們提供一個(gè)答案,僅此而已收壕。如果不僅僅關(guān)注答案的正確性妓灌,還將提交答案的過(guò)程記錄下來(lái),通過(guò)分析提交答案的過(guò)程啼器,完全可以識(shí)別出這是不是一個(gè)人在操作旬渠,這就是交互式驗(yàn)證碼的基本思路俱萍。這種驗(yàn)證碼很難通過(guò)打碼平臺(tái)來(lái)破解端壳,因?yàn)槟惚仨殞?duì)著瀏覽器,使用鼠標(biāo)對(duì)驗(yàn)證碼進(jìn)行一系列的交互操作枪蘑。

最耳熟能詳?shù)慕换ヲ?yàn)證碼莫過(guò)于 12306 的了损谦,這種驗(yàn)證碼叫做 圖中點(diǎn)選 式驗(yàn)證碼,同時(shí)提供多個(gè)圖像岳颇,讓用戶根據(jù)條件點(diǎn)擊選擇照捡。也有些驗(yàn)證碼是同時(shí)顯示 N 個(gè)變形的漢字讓你選,原理與 12306 的類似话侧,但這種驗(yàn)證碼以其極差的用戶體驗(yàn)遭到很多人的唾棄栗精,這也是大多數(shù)產(chǎn)品不愿意選用的一個(gè)原因。滑塊驗(yàn)證碼 比圖中點(diǎn)選體驗(yàn)好很多悲立,它只需要用戶使用鼠標(biāo)將滑塊從某個(gè)位置拖動(dòng)到另一個(gè)位置即可鹿寨。程序通過(guò)記錄用戶拖動(dòng)滑塊的軌跡,這一串的軌跡數(shù)據(jù)采用模式識(shí)別的手段就可以判斷出這是否是真人在操作薪夕。最簡(jiǎn)單的滑塊驗(yàn)證碼是用戶拖動(dòng)滑塊從左拖到右即可脚草,后來(lái)又出現(xiàn)了 拼圖式 的滑塊,滑塊作為圖的一部分原献,然后背景圖中有一個(gè)缺口剛好和滑塊相同形狀馏慨,需要用戶將滑塊拖到缺口中拼成一張完整的圖片。現(xiàn)在比較流行的滑塊驗(yàn)證碼有 極驗(yàn) 和 網(wǎng)易云易盾姑隅,本篇博客以極驗(yàn)的滑塊驗(yàn)證碼為例写隶,其他的滑塊驗(yàn)證碼原理是類似的。

最新的交互式驗(yàn)證碼甚至只需要用戶點(diǎn)擊一個(gè)按鈕即可驗(yàn)證粤策,不需要做任何其他的操作樟澜,譬如 極驗(yàn)的第三代行為驗(yàn)證技術(shù) 和 易盾的智能無(wú)感知驗(yàn)證碼。這種驗(yàn)證碼的破解方式和滑塊驗(yàn)證碼不一樣叮盘,我目前也沒(méi)有太多的了解秩贰,后面有時(shí)間再研究研究吧。

最后不得不說(shuō)的是柔吼,還有一種交互式驗(yàn)證碼為短信或電話驗(yàn)證碼毒费,通過(guò)將驗(yàn)證碼以短信的形式發(fā)送到你的手機(jī),或者使用語(yǔ)音機(jī)器人自動(dòng)打電話播報(bào)驗(yàn)證碼愈魏,更有甚者觅玻,需要用戶自己編輯短信將驗(yàn)證碼發(fā)送到某個(gè)號(hào)碼。對(duì)于這種驗(yàn)證碼我認(rèn)為并不能算作是 CAPTCHA培漏,因?yàn)樗玫氖怯脩舻挠邢拶Y源(手機(jī)號(hào))這個(gè)客觀限制溪厘,而并非是從技術(shù)角度來(lái)區(qū)分人和機(jī)器人的區(qū)別。如果某個(gè)人擁有大量的手機(jī)號(hào)(其實(shí)牌柄,黑產(chǎn)中確實(shí)也有專門養(yǎng)卡賣卡的)畸悬,這種驗(yàn)證手段就形同虛設(shè)了。

二珊佣、破解思路

目前蹋宦,極驗(yàn)正在推廣其第三代行為驗(yàn)證技術(shù),滑塊驗(yàn)證碼貌似已經(jīng)沒(méi)有前兩年那么流行了咒锻,不過(guò)仍然有很多網(wǎng)站還在使用滑塊驗(yàn)證碼冷冗。譬如我這篇博客就以 春秋航空的會(huì)員注冊(cè)頁(yè)面 為例。


好了惑艇,上面講了那么多蒿辙,下面就開始我們的破解之旅吧。

2.1 傳統(tǒng)爬蟲

如果采用傳統(tǒng)爬蟲的方式來(lái)破解,首先我們需要測(cè)試下正常驗(yàn)證的情況是什么樣的思灌。在 Chrome 瀏覽器中按 F12 打開開發(fā)者工具碰镜,然后拖動(dòng)滑塊到正確位置,可以觀察到 Network 面板發(fā)送的 Ajax 請(qǐng)求习瑰。

可以看到這個(gè)請(qǐng)求的參數(shù)非常復(fù)雜绪颖,每個(gè)參數(shù)的含義也完全沒(méi)有頭緒,如果要破解這個(gè)驗(yàn)證碼甜奄,則必須模擬發(fā)送這個(gè)請(qǐng)求柠横,這個(gè)請(qǐng)求的每個(gè)參數(shù)都必須弄清楚,于是我們?cè)诖a中搜索發(fā)送這個(gè)請(qǐng)求的地方课兄。但事實(shí)上到這里我們就遇到了困難牍氛,ajax.php 這個(gè)請(qǐng)求根本就搜不到,甚至在瀏覽器中下 XHR 斷點(diǎn)也不行(很顯然它并不是一個(gè) Ajax 請(qǐng)求)烟阐,這是因?yàn)闃O驗(yàn)的核心代碼經(jīng)過(guò)了代碼混淆搬俊。

這樣的代碼也就只有機(jī)器能讀懂,大多數(shù)人肯定是直接放棄了蜒茄。不過(guò)網(wǎng)上也有大量的分析文章唉擂,如果你感興趣可以自己研究下,譬如Windows應(yīng)用開發(fā) 的知乎專欄上就有幾篇介紹 極驗(yàn)驗(yàn)證碼破解的系列文章檀葛,還有 FanhuaandLuomu 的 這篇破解文章 也寫得很好玩祟,推薦。
 在這里跳過(guò)對(duì)混淆代碼的分析屿聋,總結(jié)下破解這樣的滑塊驗(yàn)證碼的思路:

  • 捕獲所有關(guān)鍵請(qǐng)求空扎;
  • 分析調(diào)試混淆的代碼,弄懂每個(gè)請(qǐng)求每個(gè)參數(shù)的含義润讥,其中肯定會(huì)有一個(gè)參數(shù)转锈,是拖動(dòng)滑塊的軌跡;
  • 驗(yàn)證碼圖片是打亂的楚殿,需要解析頁(yè)面上的樣式撮慨,并使用圖像處理方法還原出原始圖像;
  • 根據(jù)原始的圖像和滑塊位置得到缺口的偏移量勒魔;
  • 滑塊軌跡的模擬甫煞;
  • 如果參數(shù)有加密處理菇曲,還需要模擬它的加密過(guò)程冠绢;實(shí)在不行可以直接在代碼里模擬執(zhí)行頁(yè)面上的 JS.......

可見這里的工作量非常大,破解難度可想而知常潮,而且混淆的代碼隨時(shí)可能會(huì)發(fā)布新的版本弟胀,一旦版本升級(jí),參數(shù)都有可能發(fā)生變化,之前的所有分析工作都可能前功盡棄孵户。

除非實(shí)在是迫不得已萧朝,我并不推薦傳統(tǒng)的這種破解方法。首先這樣的破解方法太脆弱夏哭,不夠通用检柬,隨時(shí)可能失效;其次這樣的破解工作費(fèi)時(shí)費(fèi)力竖配,就算破解出來(lái)也得不到成就感和滿足感何址,對(duì)程序員的打擊太大,他可能再也不會(huì)玩第二次了(除非他是極客中的極客进胯,就以破解混淆代碼為樂(lè))用爪。所以,還是讓我們來(lái)看看瀏覽器爬蟲如何胁镐。

2.2 瀏覽器爬蟲

由于瀏覽器爬蟲完全是以人為第一視角偎血,你所看到的,就是瀏覽器爬蟲看到的盯漂,甚至颇玷,它能比你看到更多。我們可以大概的總結(jié)下瀏覽器爬蟲的破解思路:

  • 圖像識(shí)別就缆,找到滑塊的位置和缺口的位置亚隙;
  • 模擬鼠標(biāo)拖動(dòng),將滑塊拖到缺口位置违崇;
    沒(méi)錯(cuò)阿弃,就兩步。雖然其中會(huì)遇到一些坑羞延,但真的就這兩步渣淳。使用上一篇博客中介紹的 Selenium 技巧,可以很快的寫下下面的代碼:

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--start-maximized")
browser = webdriver.Chrome(
executable_path="./drivers/chromedriver.exe",
chrome_options=chrome_options
)
browser.get('https://account.ch.com/NonRegistrations-Regist')
Wait(browser, 60).until(
Expect.visibility_of_element_located((By.CSS_SELECTOR, "div[data-target='account-login']"))
)
email = browser.find_element_by_css_selector("div[data-target='account-login']")
email.click()
Wait(browser, 60).until(
Expect.visibility_of_element_located((By.ID, "emailRegist"))
)
register = browser.find_element_by_id("emailRegist")
register.click()
offset = get_gap_offset(browser)
drag_and_drop(browser, offset)

關(guān)鍵就在于最后兩個(gè)方法 get_gap_offset() 和 drag_and_drop()伴箩,下面就來(lái)看下這兩個(gè)方法的實(shí)現(xiàn)入愧。

三、驗(yàn)證碼圖片處理

審查驗(yàn)證碼圖片元素嗤谚,可以看到下面這樣的 HTML 代碼:
<div class="gt_cut_fullbg_slice" style="background-image: url('https://static.geetest.com/pictures/gt/3999642ae/3999642ae.webp'); background-position: -157px -58px;"></div>

這樣的代碼一共有 52 行棺蛛,每一個(gè) div 都是 10px * 58px 的小塊。我們打開這個(gè) background-image 對(duì)應(yīng)的圖片可以看出這是一張亂序的圖片巩步,這里的 background-position 用于顯示出正確的圖片旁赊。在代碼上面,可以發(fā)現(xiàn)和這里完全類似的代碼椅野,background-position 都完全一樣终畅,只是 background-image 不一樣籍胯,我們打開對(duì)應(yīng)的圖片,也是亂序的离福,但和上一張圖片對(duì)比杖狼,可以猜測(cè)出,這是帶有缺口的背景圖片妖爷。

<div class="gt_cut_bg_slice" style="background-image: url('https://static.geetest.com/pictures/gt/3999642ae/bg/fbdb18152.webp'); background-position: -157px -58px;"></div>

一個(gè)很自然的想法就是把這兩張亂序的圖片根據(jù) background-position 重組成兩張看得懂的圖片蝶涩,然后對(duì)比兩張圖片,得到缺口的偏移量絮识,然后將缺口偏移量減去滑塊偏移量子寓,就可以得到要拖動(dòng)的偏移量。如下圖所示:

其中滑塊的偏移量可以通過(guò)下面的代碼得到(其中笋除,left: 12px 就是滑塊的偏移量):

<div class="gt_slice gt_show" style="left: 12px; background-image: url('https://static.geetest.com/pictures/gt/e6e7e0440/slice/fa2d5bbd8.png'); width: 55px; height: 55px; top: 20px;"></div>

這里需要用到一點(diǎn)點(diǎn)圖像處理的知識(shí)斜友,我們采用大名鼎鼎的 Pillow,Pillow 是 Python 里的圖像處理庫(kù)(PIL:Python Image Library)垃它,在開始之前鲜屏,可以先看下它的官網(wǎng)教程,這里有一份中文文檔也可以參考国拇。計(jì)算缺口偏移量的關(guān)鍵代碼如下:

def get_slider_offset(image_url, image_url_bg, css):
image_file = io.BytesIO(requests.get(image_url).content)
im = Image.open(image_file)
image_file_bg = io.BytesIO(requests.get(image_url_bg).content)
im_bg = Image.open(image_file_bg)
# 1058 26/row => background image size = 260116
captcha = Image.new('RGB', (260, 116))
captcha_bg = Image.new('RGB', (260, 116))
for i, px in enumerate(css):
offset = convert_css_to_offset(px)
region = im.crop(offset)
region_bg = im_bg.crop(offset)
offset = convert_index_to_offset(i)
captcha.paste(region, offset)
captcha_bg.paste(region_bg, offset)
diff = ImageChops.difference(captcha, captcha_bg)
return get_slider_offset_from_diff_image(diff)

代碼很好理解洛史,就是根據(jù) css 將兩張背景圖片重新排序生成兩張新圖片,然后通過(guò) ImageChops.difference() 方法得到兩張圖片的差值圖像酱吝,最后通過(guò)差值圖像得到缺口的偏移量也殖。其中有一點(diǎn)要注意的是,Pillow 的 Image.open() 方法只支持文件务热,不支持 URL忆嗜,所以將圖片轉(zhuǎn)換為 BytesIO 對(duì)象,BytesIO 和 StringIO 一樣崎岂,是 Python 提供的在內(nèi)存中操作 bytes 和 str 的類捆毫,并且和讀寫文件具有一致的接口。

這種計(jì)算缺口位置的方法需要解析頁(yè)面源碼以及圖片的 CSS 樣式冲甘,其實(shí)還有一種更簡(jiǎn)單的方法:在顯示驗(yàn)證碼圖片時(shí)對(duì)瀏覽器進(jìn)行截圖绩卤,這個(gè)時(shí)候的圖像是完整的背景圖像;然后再點(diǎn)擊滑塊江醇,這個(gè)時(shí)候滑塊和缺口都會(huì)顯示出來(lái)濒憋,再對(duì)瀏覽器進(jìn)行截圖;分析兩次的截圖也可以計(jì)算出拖動(dòng)的偏移量陶夜。有興趣的同學(xué)可以一試凛驮。

四、模擬滑塊拖動(dòng)

在得到拖動(dòng)偏移量后律适,我們就可以通過(guò) Selenium 提供的方法來(lái)拖動(dòng)滑塊了:

def drag_and_drop(browser, offset):
knob = browser.find_element_by_class_name("gt_slider_knob")
ActionChains(browser).drag_and_drop_by_offset(knob, offset, 0).perform()

Selenium 將一系列連續(xù)的動(dòng)作封裝在 ActionChains 類 中辐烂,其中 drag_and_drop() 方法可以將一個(gè)元素拖到另一個(gè)元素上,drag_and_drop_by_offset() 方法可以指定拖動(dòng)的偏移捂贿,正是我們這里所需要的纠修。

到這里,我們已經(jīng)看到希望了厂僧,勝利就在前方扣草。不過(guò),還不能高興得太早颜屠,上面的方法雖然成功將滑塊拖到缺口位置了辰妙,但是并沒(méi)有驗(yàn)證通過(guò),頁(yè)面提示拼圖被怪物吃掉了甫窟。密浑。。

很顯然粗井,這種方法很容易被檢測(cè)出來(lái)是機(jī)器所為尔破,因?yàn)槿瞬豢赡芡夏敲纯臁S谑俏疑晕⒄{(diào)整了下程序浇衬,改成每次拖 10px懒构,然后等待 1s 再拖 10px,依次循環(huán)耘擂,不過(guò)可惜的是胆剧,這種拖法拼圖依然被怪物吃掉了,想想也是醉冤,人怎么可能拖的這么有規(guī)律呢秩霍?

于是繼續(xù)調(diào)整我的程序,在中間加入了隨機(jī)數(shù)的成分蚁阳,改成每次拖 1~20px(隨機(jī))前域,然后等待 0~2s(隨機(jī)),本想著這種方式應(yīng)該能成功了韵吨,但是事與愿違匿垄,還是被怪物吃掉,不過(guò)归粉,在測(cè)試的時(shí)候椿疗,10 次里面竟然也成功了一次。

看來(lái)極驗(yàn)對(duì)拖動(dòng)軌跡的驗(yàn)證還是很厲害的糠悼,它是如何識(shí)別出是機(jī)器拖動(dòng)的還是人拖動(dòng)的呢届榄?人在拖動(dòng)的時(shí)候,又有什么樣的規(guī)律呢倔喂?為了搞清楚這一點(diǎn)铝条,我在網(wǎng)上找了一款用于記錄鼠標(biāo)位置的小工具 MouseController靖苇,運(yùn)行之后按 F9 就可以開始或停止記錄,并可以將鼠標(biāo)軌跡保存到一個(gè) mcd 文件中班缰。使用這個(gè)工具我將手工拖動(dòng)滑塊的軌跡記錄下來(lái)贤壁,并寫了一個(gè)腳本(腳本代碼參見這里)畫出手工拖動(dòng)滑塊的軌跡圖,如下:

看到這個(gè)軌跡圖埠忘,我們應(yīng)該能想出手工拖動(dòng)的規(guī)律了:先快速向右拖動(dòng)脾拆,快到缺口位置時(shí),再減速慢調(diào)莹妒。接下來(lái)的問(wèn)題就是如何通過(guò)算法來(lái)生成這樣的軌跡了名船。

模擬滑塊拖動(dòng)的算法網(wǎng)上也有很多,有的直接根據(jù)手工拖動(dòng)的軌跡按比例生成程序要拖動(dòng)的軌跡旨怠,有的根據(jù)物理學(xué)中的加速度減速度來(lái)模擬軌跡渠驼,還有根據(jù)正切函數(shù)圖像來(lái)模擬軌跡的,可說(shuō)各有千秋鉴腻。不過(guò)它們的成功率都不能達(dá)到很滿意渴邦,我在這里介紹一種與眾不同的方法,而且成功率可以高達(dá) 99%拘哨。

我看到上面這個(gè)軌跡圖的時(shí)候谋梭,第一反應(yīng)不是上述任何一種算法,而是 jquery.easing倦青,可能是由于最近剛用 jquery.easing 實(shí)現(xiàn)了幾個(gè)動(dòng)畫效果吧瓮床。我們知道,jQuery 可以實(shí)現(xiàn)很多不同的動(dòng)畫效果产镐,譬如淡入淡出移動(dòng)等等隘庄,為了讓動(dòng)畫有好的過(guò)渡變化過(guò)程,官方提供了一個(gè) easing 屬性癣亚,但是官方?jīng)]有給出很多過(guò)渡效果丑掺。于是就有了 jquery.easing 這個(gè)插件,這個(gè)插件增加了很多種過(guò)渡效果述雾,引入之后可以讓動(dòng)畫過(guò)渡過(guò)程更加多樣化街州。Easing 有時(shí)又叫做 緩動(dòng)函數(shù),用于指定動(dòng)畫效果在執(zhí)行時(shí)的速度玻孟,使其看起來(lái)更加真實(shí)唆缴。這里有一份緩動(dòng)函數(shù)速查表,你可以在這里找到常見的緩動(dòng)函數(shù)(還可以體驗(yàn)各種緩動(dòng)函數(shù)的效果):

和上面的軌跡圖做個(gè)對(duì)比就可以發(fā)現(xiàn)黍翎,軌跡圖明顯和 easeOut 類 的緩動(dòng)函數(shù)很類似面徽,如:easeOutQuad、easeOutQuart、easeOutExpo 等等趟紊。那么我們能不能寫個(gè) Python 版的 easing 函數(shù)呢氮双?說(shuō)干就干,我們參考 jquery.easing 的源碼 實(shí)現(xiàn)了三種 easeOut 函數(shù)如下:

import numpy as np
import math
def ease_out_quad(x):
return 1 - (1 - x) * (1 - x)
def ease_out_quart(x):
return 1 - pow(1 - x, 4)
def ease_out_expo(x):
if x == 1:
return 1
else:
return 1 - pow(2, -10 * x)
def get_tracks(distance, seconds, ease_func):
tracks = [0]
offsets = [0]
for t in np.arange(0.0, seconds, 0.1):
ease = globals()[ease_func]
offset = round(ease(t/seconds) * distance)
tracks.append(offset - offsets[-1])
offsets.append(offset)
return offsets, tracks

其中 get_tracks() 方法可以根據(jù)滑塊的偏移霎匈,需要的時(shí)間(相對(duì)時(shí)間戴差,并不是準(zhǔn)確時(shí)間),以及要采用的緩動(dòng)函數(shù)生成拖動(dòng)軌跡唧躲。然后就可以通過(guò)下面的方法造挽,實(shí)現(xiàn)出想要的拖動(dòng)效果了:

def drag_and_drop(browser, offset):
knob = browser.find_element_by_class_name("gt_slider_knob")
offsets, tracks = easing.get_tracks(offset, 12, 'ease_out_expo')
ActionChains(browser).click_and_hold(knob).perform()
for x in tracks:
ActionChains(browser).move_by_offset(x, 0).perform()
ActionChains(browser).pause(0.5).release().perform()

如果你感興趣碱璃,還可以模擬出更多的效果弄痹,我們甚至可以實(shí)現(xiàn)出 easeOutBounce 這種類似小球落地時(shí)的彈跳效果。而且更有意思的是嵌器,用這種方法來(lái)拖動(dòng)滑塊肛真,竟然也可以通過(guò)驗(yàn)證。(極驗(yàn)的驗(yàn)證算法還真是讓人摸不清八健)

def ease_out_bounce(x):
n1 = 7.5625
d1 = 2.75
if x < 1 / d1 :
return n1 * x * x
elif x < 2 / d1:
x -= 1.5 / d1
return n1 * xx + 0.75
elif x < 2.5 / d1:
x -= 2.25 / d1
return n1 * x
x + 0.9375
else:
x -= 2.625 / d1
return n1 * x*x + 0.984375

總結(jié)

通過(guò)本文可以看出蚓让,破解滑塊驗(yàn)證碼,瀏覽器爬蟲要比傳統(tǒng)爬蟲簡(jiǎn)單的多讥珍。不僅僅是破解滑塊驗(yàn)證碼历极,在遇到傳統(tǒng)爬蟲很難解決的問(wèn)題時(shí),瀏覽器爬蟲都可以提供一種更方便的解決方案衷佃。但是俗話說(shuō)得好趟卸,針無(wú)雙頭利,蔗無(wú)兩頭甜氏义,凡事有利必有弊锄列,并沒(méi)有萬(wàn)能的解決方案,還是需要根據(jù)需求來(lái)取舍惯悠,譬如你的生產(chǎn)環(huán)境沒(méi)有瀏覽器邻邮,那么你不得不使用傳統(tǒng)爬蟲。但是在正常情況下克婶,我還是推薦最簡(jiǎn)單的那個(gè)選擇筒严。

文章來(lái)源

軟件測(cè)試網(wǎng)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市情萤,隨后出現(xiàn)的幾起案子萝风,更是在濱河造成了極大的恐慌,老刑警劉巖紫岩,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件规惰,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡泉蝌,警方通過(guò)查閱死者的電腦和手機(jī)歇万,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門揩晴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人贪磺,你說(shuō)我怎么就攤上這事硫兰。” “怎么了寒锚?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵劫映,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我刹前,道長(zhǎng)泳赋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任喇喉,我火速辦了婚禮祖今,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拣技。我一直安慰自己千诬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布膏斤。 她就那樣靜靜地躺著徐绑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪莫辨。 梳的紋絲不亂的頭發(fā)上傲茄,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音衔掸,去河邊找鬼烫幕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛敞映,可吹牛的內(nèi)容都是我干的较曼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼振愿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼捷犹!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起冕末,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤萍歉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后档桃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體枪孩,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蔑舞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拒担。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖攻询,靈堂內(nèi)的尸體忽然破棺而出从撼,到底是詐尸還是另有隱情,我是刑警寧澤钧栖,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布低零,位于F島的核電站,受9級(jí)特大地震影響拯杠,放射性物質(zhì)發(fā)生泄漏掏婶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一阴挣、第九天 我趴在偏房一處隱蔽的房頂上張望气堕。 院中可真熱鬧纺腊,春花似錦畔咧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至壹粟,卻和暖如春拜隧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背趁仙。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工洪添, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雀费。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓干奢,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親盏袄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子忿峻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1.前言 既然有爬蟲的存在那就有反爬蟲技術(shù)的存在,驗(yàn)證碼是常見手段辕羽,不過(guò)最近發(fā)現(xiàn)不少網(wǎng)站使用極限驗(yàn)證碼逛尚。對(duì)于普通驗(yàn)...
    無(wú)事扯淡閱讀 2,591評(píng)論 1 9
  • 今早6:20起床,起床后做了兩次“叩齒吞津”刁愿,唾液產(chǎn)生產(chǎn)生不多绰寞。爾后洗漱早讀,大概7:40出門上班,不到八點(diǎn)的時(shí)候...
    小五先生fiver閱讀 221評(píng)論 0 0