1. 程式人生 > >高階Python爬蟲實戰:破解極驗滑動驗證碼

高階Python爬蟲實戰:破解極驗滑動驗證碼

今天給大家帶來的是極驗驗證碼的selenium破解之法,是不是有點小激動呢,小夥伴們等不及了,讓我們趕緊直入主題吧。

虎X網註冊

這次我們是拿虎X開刀,註冊賬號的時候需要滑動圖片到缺口位置,這種驗證碼我們現在也經常遇到,這個就不用詳細介紹了吧 

640?wx_fmt=png&wxfrom=5&wx_lazy=1

針對這種驗證碼我們首先確定了使用selenium模擬滑動破解方式,selenium滑鼠移動點選拖動都比較簡單,那麼問題就在於拖動多少距離,眼睛看起來很直觀,但是程式怎麼獲取呢?利用影象識別......,額,這個只能想想了吧。不如看看網頁原始碼或者請求資訊,看看有沒有有效的資訊。

檢視網頁資訊

滑鼠右鍵點選到圖片上,檢視元素 

640?wx_fmt=png&wxfrom=5&wx_lazy=1

這一瞬間的圖片,還好我二十幾年的麒麟臂沒白練,我們看看元素檢視到的都是什麼東西 640?wx_fmt=png

這看起來有點奇怪哦,有個圖片連結,還有位置資訊,而且還那麼多,先把圖片連結拷貝到瀏覽器裡訪問下看看 

640?wx_fmt=png 

WTF,這是什麼鬼?注意到那個像豬尾巴一樣的6了嗎?還有那個小箭頭,跟上面完整圖片對比一下,發現把箭頭挪動到小6旁邊,豬尾巴就成功了。當然你仔細觀察的話,還有其他的比如文字也是類似。那麼我們可以確認這張圖片應該是被打亂的,如果我們可以把它拼起來,是不是就離計算缺口位置比較近了。現在我們應該要注意到元素檢視裡後面的位置資訊了,那麼多,看起來應該跟這個打亂順序有點關係吧。我們來確認一下。我的想法是這樣子的,既然這個位置和拼圖有關,而且再看我們上面麒麟臂截的圖,我再標記一下 

640?wx_fmt=png

 我們點選檢視元素的時候,瀏覽器會幫我們突出顯示一下,本來我是在圖片上點選檢視的,按照我的想法,它不是應該整張圖片突出顯示一下嗎?看起來好像不是這麼回事,只有那麼一小部分,而且上面還有元素資訊,寬高類名,再回去看看圖3,位置座標裡,前面應該是x軸,後面是y軸,y軸只有58和0,再根據圖2一看,圖片分為上下兩部分,再數一下div的數量,26塊,每一塊寬10x高58。按照這個來算的話,那麼整個圖片的寬就是260,高116,用截圖工具去拉一下圖片的寬高,基本吻合 

640?wx_fmt=gif

接下來就是確定怎麼拼了。這裡很抱歉的告訴大家,豬沒了,等我寫到這裡再去檢視網頁的時候,圖片已經重新整理了。所以接下來的截圖可能不一樣,在這裡提前跟大家說明一下。反正就是找特徵點嘛,每個圖片應該都有的。先隨便找一個特徵點,檢視元素,看它定位到那個div元素那裡,然後再看看後面的位置。基本就是這樣,所以我們找圖片既然和位置有關,那麼我們最好選一些位置明顯的地方,比如中間,或者兩邊。 

640?wx_fmt=png 

這個差不多算中間位置了吧,查那麼一點點無所謂了 

640?wx_fmt=png

我去,這......跟我想的不太一樣呀,再找兩張看看,代表性及其強烈的 

640?wx_fmt=png 

640?wx_fmt=png

640?wx_fmt=png 640?wx_fmt=png

為了防止有人說我水字數,另外兩個角就不截圖了。到這一步可能有人納悶了,為啥?你剛才說圖片寬度260,為什麼座標裡出現了289這樣的座標,這不就是超標了嗎?一開始我也有這樣的疑惑,可能我們看到圖片比實際的小,也許人家在圖片外面還留了邊框呢,我一開始是這麼想的。但是這個座標是前面url裡面的圖片座標,然後我就去看了一下圖4 

640?wx_fmt=gif 

這個圖片盡然比較大,座標問題有答案了,但是這個跟260有什麼關係呢?打亂的圖片比較大,拼好的小,那它是怎麼拼的呢?幸好我們看到了一個比較有用資訊 

640?wx_fmt=png

640?wx_fmt=png

看到這個-1px了嗎?它成功引起了我的注意,因為按照我的想法,如果是從拼圖裡拿出一部分拼成一個完成圖片的話,那麼最左邊拿出來的圖片,應該是從(0,0),(0,58),但是我們看到的是(1,0),(1,58),y值還是比較符合我們的預期的,第一部分從0開始,高58,第二部分從58開始。但是x值有點問題,按照1作為起點,那第二個應該是11,因為寬度是10,這是確定的,我們找找看

640?wx_fmt=png

是13,難道每一小塊前面都多餘了1個畫素?按照這種的話也應該是12呀,按照這種方式我們繼續找一找剩下的,通過分析我們發現每個小塊+12作為下一個小塊的起點。這樣的話左右各去掉一個畫素,寬度不就是10了嗎?而且每個小塊是12,26個是312,跟我們看到的拼圖大小差不多,說明我們分析的是正確的。按照元素裡提供的座標,取寬度為10的大小即可。接下來分析一下這些座標的意義。

座標分析

分析一下我們圖9到圖12的截圖,首先說圖9,我本來覺得它x、y應該是0,就算不是0,也應該是各位數字吧,結果的y是58,這個算到下半截圖片區域了,x是157,跑中場去了。圖11呢,你的x應該在300左右,y應該100以上吧,結果y是0,到上半段,x是205,在中場偏後,離守門員還遠呢。這是怎麼肥事?不過我們發現了,圖9在元素裡是第一個,圖11在元素裡是最後一個,再結合座標前面的y值全是58,後面的y值全是0,符合我們上半段下半段顛倒的想法了,然後你再分別檢視圖9右邊/圖11左邊的元素就會發現,和元素裡面div的順序一樣。到這裡就差不多了。

總結一下:最終的圖片就是把拼圖,即圖4,按照x=157、y=58、w=10、h=58截取出來,放在上半部分第一個位置,x=145、y=58、w=10、h=58截取出來放在上半部分第二個位置,緊挨著第一個,以此類推,拼成一張整圖。 

640?wx_fmt=png 

這個就是我拼出來的,恩,很好,很不錯嘛小夥子。不過好像哪裡不對,缺口嘞。仔細看看網頁元素 

640?wx_fmt=png原來一個是fullbg,一個是cutbg,這個名字就很有寓意嘛,那就好了,再把cutbg拼一下看看 

640?wx_fmt=png 

這回就對上了。現在的問題就變成怎麼計算缺口位置了

缺口位置

我覺得可能會有計算兩張圖片不同位置的方式吧,度娘來一發,然後獲取了python實戰===用python對比兩張圖片的不同,然後發現了ImageChops.difference這個介面,結果你們知道的,不準確,為啥捏?仔細看拼好的兩張圖,除了缺口還有其他地方不一樣呀。看到圖16缺口後面那個陰影沒,讓我的心裡蒙上了一層陰影,再觀察其他的圖片,基本都有類似的,這可怎麼辦?這在後面還好說,如果是在前面呢,那不就計算到陰影裡去了嘛。如果這個對比有一個容差就好了,我以前用按鍵精靈的時候好像就有這種嘛,這個好不智慧呀。既然它是對比畫素,我直接取畫素對比一下不就得了,而且我還不給它用==,給它一個範圍,如果色差在這個範圍內就算一樣了,這樣不就有容差了嗎?這個缺口一般都非常明顯,而陰影跟背景又很模糊,應該是可行的。思路就是獲取圖片的寬高,然後一個畫素一個畫素的遍歷對比。

色差

這個色差怎麼確定?一種方式就是除錯,這種是比較麻煩的,還有一種方式就是獲取多張圖片,全圖和缺陷圖,然後使用取色工具,取對應位置的顏色值,確定一個大概範圍。距離確定了,下面就是移動了

selenium模擬移動

selenium的模擬操作網上介紹很多,這裡我們只要確認需要哪些介面就行了。 ActionChains方法:

  • movetoelement(to_element) - 滑鼠移動到某個元素

  • clickandhold(on_element =None) - 點選滑鼠左鍵,不鬆開

  • movebyoffset(xoffset,yoffset) - 滑鼠從當前位置移動到某個座標

  • release(on_element = None) - 在某個元素位置鬆開滑鼠左鍵

  • perform() - 執行操作,記住這個很重要,呼叫上面的方法後,一定要執行perform才能真正執行

selenium的操作我就不詳細描述了,這裡用到的都是比較簡單的用法。

原理分析就完了,這一次必須要貼程式碼了,否則可能很多人完成不了,也有利於大家的理解。

由於篇幅有限,下面為部分程式碼,完整程式碼請關注公眾號“程式設計狗”後回覆“0419”獲取

  1. # -*- coding: utf-8 -*-

  2. import random

  3. import time, re

  4. from selenium import webdriver

  5. from selenium.common.exceptions importTimeoutException

  6. from selenium.webdriver.common.by importBy

  7. from selenium.webdriver.support.wait importWebDriverWait

  8. from selenium.webdriver.support import expected_conditions as EC

  9. from selenium.webdriver.common.action_chains importActionChains

  10. from PIL importImage

  11. import requests

  12. from io importBytesIO

  13. classHuXiu(object):

  14. def __init__(self):

  15.        chrome_option = webdriver.ChromeOptions()

  16. # chrome_option.set_headless()

  17.        self.driver = webdriver.Chrome(executable_path=r"/usr1/webdrivers/chromedriver", chrome_options=chrome_option)

  18.        self.driver.set_window_size(1440, 900)

  19. def visit_index(self):

  20.        self.driver.get("https://www.huxiu.com/")

  21. WebDriverWait(self.driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//*[@class="js-register"]')))

  22.        reg_element = self.driver.find_element_by_xpath('//*[@class="js-register"]')

  23.        reg_element.click()

  24. WebDriverWait(self.driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_slider_knob gt_show"]')))

  25. # 進入模擬拖動流程

  26.        self.analog_drag()

  27. def analog_drag(self):

  28. #滑鼠移動到拖動按鈕,顯示出拖動圖片

  29.        element = self.driver.find_element_by_xpath('//div[@class="gt_slider_knob gt_show"]')

  30. ActionChains(self.driver).move_to_element(element).perform()

  31.        time.sleep(3)

  32. # 重新整理一下極驗圖片

  33.        element = self.driver.find_element_by_xpath('//a[@class="gt_refresh_button"]')

  34.        element.click()

  35.        time.sleep(1)

  36. # 獲取圖片地址和位置座標列表

  37.        cut_image_url, cut_location = self.get_image_url('//div[@class="gt_cut_bg_slice"]')

  38.        full_image_url, full_location = self.get_image_url('//div[@class="gt_cut_fullbg_slice"]')

  39. # 根據座標拼接圖片

  40.        cut_image = self.mosaic_image(cut_image_url, cut_location)

  41.        full_image = self.mosaic_image(full_image_url, full_location)

  42. # 儲存圖片方便檢視

  43.        cut_image.save("cut.jpg")

  44.        full_image.save("full.jpg")

  45. # 根據兩個圖片計算距離

  46.        distance = self.get_offset_distance(cut_image, full_image)

  47. # 開始移動

  48.        self.start_move(distance)

  49. # 如果出現error

  50. try:

  51. WebDriverWait(self.driver, 5, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_ajax_tip gt_error"]')))

  52. print("驗證失敗")

  53. return

  54. exceptTimeoutExceptionas e:

  55. pass

  56. # 判斷是否驗證成功

  57. try:

  58. WebDriverWait(self.driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//div[@class="gt_ajax_tip gt_success"]')))

  59. exceptTimeoutException:

  60. print("again times")

  61.            time.sleep(5)

  62. # 失敗後遞迴執行拖動

  63.            self.analog_drag()

  64. else:

  65. # 成功後輸入手機號,傳送驗證碼

  66.            self.register()

  67. # 獲取圖片和位置列表

  68. def get_image_url(self, xpath):

  69.        link = re.compile('background-image: url\("(.*?)"\); background-position: (.*?)px (.*?)px;')

  70.        elements = self.driver.find_elements_by_xpath(xpath)

  71.        image_url = None

  72.        location = list()

  73. for element in elements:

  74.            style = element.get_attribute("style")

  75.            groups = link.search(style)

  76.            url = groups[1]

  77.            x_pos = groups[2]

  78.            y_pos = groups[3]

  79.            location.append((int(x_pos), int(y_pos)))

  80.            image_url = url

  81. return

    相關推薦

    高階Python爬蟲實戰破解滑動驗證

    今天給大家帶來的是極驗驗證碼的selenium破解之法,是不是有點小激動呢,小夥伴們等不及了,讓

    破解滑動驗證

    ora 十六 rgb 遊戲 form 保存 過程 每天 網頁截圖 閱讀目錄 一 介紹 二 實現 三 說明 一 介紹 一些網站會在正常的賬號密碼認證之外加一些驗證碼,以此來明確地區分人/機行為,從一定程度上達到反爬的效果,對於簡單的校驗碼Tesseroc

    Python網路爬蟲滑動驗證識別

    驗證碼分析 使用程式碼完成極驗驗證碼的識別,需要了解一下幾點: 通過該驗證碼的識別動作為:點選並拖拽滑塊 - 滑動滑塊至缺口處 - 釋放滑鼠 該驗證碼增加了機器學習來識別拖動的軌跡,即:

    python+selenium十三破解簡單的圖形驗證 python+selenium十三破解簡單的圖形驗證

    python+selenium十三:破解簡單的圖形驗證碼   此方法可破解簡單的驗證碼,如:  注:中文識別正在尋找辦法 安裝: 1、python3 2、Pillow 3、pytesseract 4、tesseract-o

    破解(geetest)驗證

    最近在搞爬蟲的時候在好幾個網站都碰到了一種叫做geetest的滑動條驗證碼,一直沒有太好的辦法只能在觸發這個驗證碼後發個報警去手動處理一下。http://www.geetest.com/exp_embed是他們官網的樣例。 後來研究了下覺得要破解這

    95行代滑動驗證?是遠遠不夠的!大牛石錘!

    過程 零基礎 行處理 ima 挑戰 卷積 卷積神經網絡 都在 一場 一直以來,極驗堅持的理念是:醉心技術,以不變之變以應萬變。通過不斷地鉆研技術,升級產品,每日叠代更新,全網聯動聯防。在攻防過程中,始終將對手甩在身後,我們團隊始終堅守著,因為我們相信行動才是最好的回應。

    295day(圖形驗證的識別,滑動驗證識別原理)

    《2018年7月24日》【連續295天】 標題:圖形驗證碼的識別,極驗滑動驗證碼識別原理; 內容: 圖形驗證碼: 測試: import tesserocr from PIL import Image image =Image.open('code.jpg')

    thinkphp整合滑動驗證原始碼演示下載

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>使用者1</title><meta http-equiv="Cache-Control" conte

    爬蟲進階教程(GEETEST)驗證破解教程

    摘要: 爬蟲最大的敵人之一是什麼?沒錯,驗證碼!Geetest作為提供驗證碼服務的行家,市場佔有率還是蠻高的。遇到Geetest提供的滑動驗證碼怎麼破?授人予魚不如授人予漁,接下來就為大家呈現本教程的精彩內容。 一、前言 爬蟲最大的敵人之一是什麼?沒錯,驗證碼!Ge

    python爬蟲實戰利用scrapy,短短50行代下載整站短視頻

    start mongodb efi 本地 rtp 公司 loader 右鍵 more 近日,有朋友向我求助一件小事兒,他在一個短視頻app上看到一個好玩兒的段子,想下載下來,可死活找不到下載的方法。這忙我得幫,少不得就抓包分析了一下這個app,找到了視頻的下載鏈接,幫他解決

    Python爬蟲實戰股票資料定向爬蟲

    功能簡介 目標: 獲取上交所和深交所所有股票的名稱和交易資訊。 輸出: 儲存到檔案中。 技術路線: requests—bs4–re 語言:python3.5 說明 網站選擇原則: 股票資訊靜態存在於html頁面中,非js程式碼生成,沒有Robbts

    Python爬蟲實戰抓取並儲存百度雲資源(附程式碼)

    尋找並分析百度雲的轉存api 首先你得有一個百度雲盤的賬號,然後登入,用瀏覽器(這裡用火狐瀏覽器做示範)開啟一個分享連結。F12開啟控制檯進行抓包。手動進行轉存操作:全選檔案->儲存到網盤->選擇路徑->確定。點選【確定】前建議先清空一下抓包記錄,這樣可以精確定位到轉存的api,這就是

    python爬蟲實戰利用scrapy,短短50行程式碼下載整站短視訊

    近日,有朋友向我求助一件小事兒,他在一個短視訊app上看到一個好玩兒的段子,想下載下來,可死活找不到下載的方法。這忙我得幫,少不得就抓包分析了一下這個app,找到了視訊的下載連結,幫他解決了這個小問題。 因為這個事兒,勾起了我另一個念頭,這不最近一直想把python爬蟲方面的知識梳理梳理嗎,乾脆藉機行事,正湊

    零基礎Python爬蟲實戰豆瓣電影TOP250

    我們曾經抓取過貓眼電影TOP100,並進行了簡單的分析。但是眾所周知,豆瓣的使用者比較小眾、比較獨特,那麼豆瓣的TOP250又會是哪些電影呢? 我在整理程式碼的時候突然發現一年多以前的爬蟲程式碼竟然還能使用……那今天就用它來演示下,如何通過urllib+BeautifulSoup來快

    Python爬蟲實戰 批量採集股票資料,並儲存到Excel中

    小編說:通過本文,讀者可以掌握分析網頁的技巧、Python編寫網路程式的方法、Excel的操作,以及正則表示式的使用。這些都是爬蟲專案中必備的知識和技能。本文選自《Python帶我起飛》。 例項描述:通過編寫爬蟲,將指定日期時段內的全部上市公司股票資料爬取下來,並按照股

    Python爬蟲實戰使用Selenium抓取QQ空間好友說說

    前面我們接觸到的,都是使用requests+BeautifulSoup組合對靜態網頁進行請求和資料解析,若是JS生成的內容,也介紹了通過尋找API藉口來獲取資料。 但是有的時候,網頁資料由JS生成,API藉口又死活找不著或者是API藉口地址隨機變換,時間不等人

    python爬蟲實戰利用pyquery爬取貓眼電影TOP100榜單內容-2

    上次利用pyquery爬取貓眼電影TOP100榜單內容的爬蟲程式碼中點選開啟連結 存在幾個不合理點。1. 第一個就是自定義的create_file(檔案存在判斷及建立)函式。我在後來的python檔案功能相關學習中,發現這個自定義函式屬於重複造輪子功能。因為 for data

    python爬蟲實戰基礎爬蟲(使用BeautifulSoup4等)

      以前學習寫爬蟲程式時候,我沒有系統地學習爬蟲最基本的模組框架,只是實現自己的目標而寫出來的,最近學習基礎的爬蟲,但含有完整的結構,大型爬蟲含有的基礎模組,此專案也有,“麻雀雖小,五臟俱全”,只是沒有考慮優化和穩健性問題。               爬蟲框架 爬蟲框架包括這五大模組,簡單介紹作用:1.爬蟲

    Python 新手實戰之機器學習實現簡單驗證識別(一)用PIL簡單繪製驗證

    驗證碼生成 from PIL import Image, ImageDraw, ImageFont import random, os def draw(): #隨機生成背景顏色 (RGB顏色範圍為0-255,越高越接近白色),背景顏色不宜過深,

    Python爬蟲實例 動態ip+抓包+驗證自動識別

    PE IT agent 也有 pass ttr timeout edi targe   最近出於某種不可描述的原因,需要爬一段數據,大概長這樣:      是一個價格走勢圖,鼠標移到上面會顯示某個時刻的價格,需要爬下來日期和價格。   第一步肯定先看源代碼,找到了這