用Python識別圖形驗證碼,實現自動登陸!

2021-01-15 Python編程


驗證碼有圖形驗證碼、極驗滑動驗證碼、點觸驗證碼、宮格驗證碼。這回重點講講圖形驗證碼的識別。


雖說圖形驗證碼最簡單,但是對於我這等新手,還是要苦學一番。首先尋找測試網站,網站選的是如雲閣小說網,小網站不怕被封。他們的驗證碼一般如下:



可以看出有微弱的幹擾線和較強的幹擾點,驗證碼是沒有邊框的,這裡為了排版好看,我加上去的...


1.  灰度處理   把彩色驗證碼圖片轉為灰色的圖片。



import cv2

image = cv2.imread('1.jpeg', 0)
cv2.imwrite('1.jpg', image)


2.  二值化處理   將圖片處理為只有黑白兩色的圖片,這裡發現幹擾線沒有了,這就意味著我們只需要處理幹擾點即可。



import cv2

image = cv2.imread('1.jpeg', 0)
ret, image = cv2.threshold(image, 100, 255, 1)
height, width = image.shape
new_image = image[0:height, 0:150]
cv2.imwrite('1.jpg', new_image)


3.  降噪處理   去除小黑點,也就是孤立的黑色像素點。



點降噪原理就是檢測黑色點相鄰的8個點,判斷8個點的顏色情況。如果全是白點,那麼就認為這個點是白色的,做黑點變白點處理。如⑤點處,以田字格來看,相鄰共有8個區域。



①②③點坐標如下圖,同理可知④⑤⑥⑦⑧⑨點坐標情況



降噪代碼如下:


import cv2
import numpy as np
from PIL import Image


def inverse_color(image, col_range):
    
    image = cv2.imread(image, 0)
    
    ret, image = cv2.threshold(image, 110, 255, 1)
    
    height, width = image.shape
    
    img2 = image.copy()
    for i in range(height):
        for j in range(width):
            img2[i, j] = (255 - image[i, j])
    img = np.array(img2)
    
    height, width = img.shape
    new_image = img[0:height, col_range[0]:col_range[1]]
    cv2.imwrite('handle_one.png', new_image)
    image = Image.open('handle_one.png')
    return image


def clear_noise(img):
    
    x, y = img.width, img.height
    for i in range(x):
        for j in range(y):
            if sum_9_region(img, i, j) < 2:
                
                img.putpixel((i, j), 255)
    img = np.array(img)
    cv2.imwrite('handle_two.png', img)
    img = Image.open('handle_two.png')
    return img


def sum_9_region(img, x, y):
    """
    田字格
    """
    
    cur_pixel = img.getpixel((x, y))
    width = img.width
    height = img.height

    if cur_pixel == 255:  
        return 10

    if y == 0:  
        if x == 0:  
            
            sum_1 = cur_pixel + img.getpixel((x, y + 1)) + img.getpixel((x + 1, y)) + img.getpixel((x + 1, y + 1))
            return 4 - sum_1 / 255
        elif x == width - 1:  
            sum_2 = cur_pixel + img.getpixel((x, y + 1)) + img.getpixel((x - 1, y)) + img.getpixel((x - 1, y + 1))
            return 4 - sum_2 / 255
        else:  
            sum_3 = img.getpixel((x - 1, y)) + img.getpixel((x - 1, y + 1)) + cur_pixel + img.getpixel((x, y + 1)) + img.getpixel((x + 1, y)) + img.getpixel((x + 1, y + 1))
            return 6 - sum_3 / 255

    elif y == height - 1:  
        if x == 0:  
            
            sum_4 = cur_pixel + img.getpixel((x + 1, y)) + img.getpixel((x + 1, y - 1)) + img.getpixel((x, y - 1))
            return 4 - sum_4 / 255
        elif x == width - 1:  
            sum_5 = cur_pixel + img.getpixel((x, y - 1)) + img.getpixel((x - 1, y)) + img.getpixel((x - 1, y - 1))
            return 4 - sum_5 / 255
        else:  
            sum_6 = cur_pixel + img.getpixel((x - 1, y)) + img.getpixel((x + 1, y)) + img.getpixel((x, y - 1)) + img.getpixel((x - 1, y - 1)) + img.getpixel((x + 1, y - 1))
            return 6 - sum_6 / 255

    else:  
        if x == 0:  
            sum_7 = img.getpixel((x, y - 1)) + cur_pixel + img.getpixel((x, y + 1)) + img.getpixel((x + 1, y - 1)) + img.getpixel((x + 1, y)) + img.getpixel((x + 1, y + 1))
            return 6 - sum_7 / 255
        elif x == width - 1:  
            sum_8 = img.getpixel((x, y - 1)) + cur_pixel + img.getpixel((x, y + 1)) + img.getpixel((x - 1, y - 1)) + img.getpixel((x - 1, y)) + img.getpixel((x - 1, y + 1))
            return 6 - sum_8 / 255
        else:  
            sum_9 = img.getpixel((x - 1, y - 1)) + img.getpixel((x - 1, y)) + img.getpixel((x - 1, y + 1)) + img.getpixel((x, y - 1)) + cur_pixel + img.getpixel((x, y + 1)) + img.getpixel((x + 1, y - 1)) + img.getpixel((x + 1, y)) + img.getpixel((x + 1, y + 1))
            return 9 - sum_9 / 255


def main():
    img = '1.jpeg'
    img = inverse_color(img, (0, 160))
    clear_noise(img)


if __name__ == '__main__':
    main()


解決最大的問題後,接下來就是實現自動登陸。首先使用selenium自動點擊登陸按鈕。



到登陸界面後,利用selenium自動輸入用戶名,密碼,對驗證碼區域進行截圖。而後對驗證碼截圖進行處理,最後成功獲取驗證碼。


這裡為什麼是截圖呢,原因是驗證碼圖片一直在變化。比如說我現在複製這個8863驗證碼的圖片連結,在新的標籤頁打開,會發現驗證碼改變了,不是8863,而是另外一張驗證碼圖片。那麼我們通過獲取當前頁面的驗證碼連結,從而來獲取驗證碼圖片,這種方法肯定是不可行的。


通過查閱相關資料,知道了帶cookies訪問驗證碼連結頁面,能夠成功解決這個問題。不過由於相關的庫沒導入成功,也就放棄了。等下回做驗證碼機器學習的時候,再給予解決。



登陸成功



自動登陸代碼如下:


import re
import cv2
import time
import numpy as np
import pytesseract
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


USER = '你的用戶名'
PASSWORD = '你的密碼'
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 20)


def inverse_color(image, col_range):...


def clear_noise(img):...


def sum_9_region(img, x, y):...


def auto_login():
    """
    實現網頁自動登陸
    """
    url = 'http://www.quanben9.com/'
    browser.get(url)
    
    button = browser.find_element_by_css_selector('#top1 > div > a:nth-child(3)')
    button.click()
    
    input_first = browser.find_element_by_name('username')
    input_first.send_keys(USER)
    
    input_second = browser.find_element_by_name('password')
    input_second.send_keys(PASSWORD)
    
    browser.save_screenshot('Login_page.png')
    photo = Image.open('login_page.png')
    box = (1210, 710, 1360, 755)
    photo.crop(box).save('Verification.png')
    
    handle_verification_code('Verification.png')
    
    image = Image.open('handle_two.png')
    image.show()
    result = pytesseract.image_to_string(image)
    
    result = re.sub('[a-zA-Z』!"#$%&'()*+,-./:;<=>?@,。?★、…【】《》?「」『』![\]^_`{|}~]+', '', result.replace(' ', ''), re.S)
    print(result)
    
    if len(result) == 4:
        
        input_third = browser.find_element_by_name('code')
        input_third.send_keys(result)
        time.sleep(2)
        
        button_2 = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'body > div.main > div > form > ul > li:nth-child(5) > input[type="submit"]')))
        button_2.click()
        time.sleep(5)
    else:
        return auto_login()


def handle_verification_code(img):
    img = inverse_color(img, (0, 160))
    img = clear_noise(img)
    return img


def main():
    auto_login()


if __name__ == '__main__':
    main()
    
    exit()


這裡用會聲會影給視頻加了個BGM,不過結尾的時候不是很搭,水平有限吶!還是得好好多學習。視頻如下:



···  END  ···


●編號582,輸入編號直達本文

●輸入m獲取文章目錄

算法與數據結構

更多推薦25個技術類公眾微信

涵蓋:程序人生、算法與數據結構、黑客技術與網絡安全、大數據技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。


相關焦點

  • Python驗證碼識別:利用pytesser識別簡單圖形驗證碼
    圖形通常由點、線、面、體等幾何元素和灰度、色彩、線型、線寬等非幾何屬性組成。計算機涉及到的幾何圖形處理一般有 2維到n維圖形處理,邊界區分,面積計算,體積計算,扭曲變形校正。對於顏色則有色彩空間的計算與轉換,圖形上色,陰影,色差處理等等。在破解驗證碼中需要用到的知識一般是 像素,線,面等基本2維圖形元素的處理和色差分析。
  • 用python識別驗證碼
    前言經常大家在做自動化測試或者做網絡爬蟲的時候,都很容易遇到驗證碼。今天,我們就簡單的說下,怎麼用python來處理驗證碼。
  • mac使用python識別圖形驗證碼!
    前言首先這篇文章,主要是研究圖形驗證碼,後期會不定時拓展內容。
  • 使用Python和Tesseract來識別圖形驗證碼
    一、關於圖形驗證碼識別與tesseractOCR儘管多數圖型驗證碼只有區區幾個數字或字母,但你可能聽說了,在進行機器識別的過程中,你要收集樣本,對圖片去噪、二值化、提取字符、計算特徵,甚至還要祭出神經網絡去訓練數據進行機器學習……還沒開幹,退堂鼓早打響三遍了。
  • 驗證碼識別實例,python簡單圖像處理和實現
    基本識別原理概述:1、每一幅圖像在構成上,都是由一個個像素組成的矩陣,每一個像素為單元格。2、 彩色圖像的像素的由三原色(紅,綠,藍)構成元組,灰度圖像的像素是一個單值,每個像素的值範圍為(0,255)。
  • 12306圖形驗證碼讓人"吐槽" 驗證碼到底有什麼用
    在年底的網絡購票高峰中,中國鐵路客戶服務中心的12306圖形驗證碼系統被很多購票者「吐槽」。人們不禁要問,複雜的驗證碼系統,到底有什麼用?其實,驗證碼存在的最大意義,就是區分在頁面上進行輸入操作的是人還是自動化的軟體。
  • Python3網絡爬蟲課程 8.1圖形驗證碼的識別
    目前,很多網站都採取了各種各樣的反爬措施,其中之一便是使用驗證碼.隨著技術的發展,驗證碼卻來越複雜,花樣越來越多,爬蟲的工作也變得愈加複雜,本節將介紹圖形驗證碼的識別.圖形驗證碼我們首先將識別最簡單的驗證碼,圖形驗證碼.目標我們將以知網為例講解使用 OCR 技術識別圖形驗證碼.
  • 12306將剔除辨識率低圖形驗證碼
    對此,12306相關負責人昨日向記者表示,為防止搶票軟體自動識別,相關圖形做了技術處理,但未來將會剔除一些辨識度低的圖片。  圖片技術處理為防搶票軟體  「12306的驗證碼,已經擊敗了全國99%的購票者,我已經找不到回家的路了。」近日,春運購買火車票期間,不少網友發帖吐槽12306的圖形驗證碼。
  • 12306網站驗證碼遭拍磚 「驗證碼」本意是安全不是麻煩
    動態視頻驗證碼技術上具有先進性,但網站投入成本較高,目前還未普及。  為什麼一定要用圖形驗證碼?  「黃牛不可能人工去買票,必然是使用搶票軟體。」牛凱說,黃牛可能手中囤積大量的身份證號碼,刷票軟體可以自動登錄,用真實的身份證信息進行自動下單交易,由於整個過程由軟體自動完成,執行速度比正常用戶的手工操作快幾十倍乃至上百倍,因此可以搶得先機,大量刷票。
  • 能跑源碼,還提供數據集:這裡有一個入門企業級驗證碼識別項目
    前言網上關於驗證麼識別的開源項目眾多,但大多是學術型文章或者僅僅是一個測試 demo,那麼企業級的驗證碼識別究竟是怎樣的呢?前方高能預警,這是一個生產水準的驗證碼識別項目,筆者可以向你們保證,它一定會是各位所見過的文章中最實用的,你甚至可以不需要懂代碼寫代碼就能輕鬆使用它訓練一個 99 識別率的模型。這才是企業級應該有的樣子:算法開發負責框架,訓練只需要一個實習生。
  • 圖形驗證碼難防黃牛 今年網購車票超8成無驗證碼
    中國鐵路總公司表示,今年春運網絡購票需要驗證碼的比例將被壓縮到15%以下。昨天,老牌搶票軟體360瀏覽器表示通過大數據分析,今年春運搶票初期,12306的圖形驗證碼並沒有比去年增加難度,他們發現圖形驗證碼已經不是鐵路防止黃牛倒票的主要技術手段,鐵路正在通過更加嚴格的實名認證等其他方式來防黃牛,提高了用戶的購票體驗。
  • Python3爬蟲-10:Tesseract 圖像識別
    「人生苦短,快用Python」在爬蟲過程中,經常會遇到各種驗證碼
  • 最全的 Python 反爬蟲及應對方案!
    實現難度:★★★ 5. 驗證碼驗證碼是一種區分用戶是計算機還是人的公共全自動程序。可以防止:惡意破解密碼、刷票、論壇灌水,有效防止某個黑客對某一個特定註冊用戶用特定程序暴力破解方式進行不斷的登陸嘗試,實際上用驗證碼是現在很多網站通行的方式.圖片驗證碼複雜型打碼平臺僱傭了人力,專門幫人識別驗證碼。識別完把結果傳回去。總共的過程用不了幾秒時間。這樣的打碼平臺還有記憶功能。
  • 復旦大學肖仰華:12306的驗證碼已不再安全,未來屬於智能驗證碼
    之後設計一個帶參數剛體運動的軌跡模擬模型,參數隨機化之後模擬真人的軌跡拖動,從而實現破解。12306圖形驗證碼除了拖拽驗證碼,據說難倒了很多購票者的12306的驗證碼其實也可以被破解。12306的驗證碼本質上在做圖片中的對象識別,因此可以利用已經相當成熟的ImageNet相關算法,而ImageNet相關算法對圖片中的實體識別已經到達很高的準確率。
  • 要選對12306購票圖形驗證碼 比高考還難
    吐槽驗證碼成購票「攔路虎」「買張車票,眼睛都看成對眼了,我容易嗎我?」「人類何苦為難人類」……昨日,記者登錄各大鐵路論壇、微博看到了各種對於圖形驗證碼的吐槽。網友們紛紛表示,五花八門的圖形讓人看得眼花繚亂,有點像遊戲「找你妹」和「連連看」,大大降低了自己的購票速度和成功率。還有網友感慨:「搶過票,才知道自己見識少」。其中網友「注釋回憶」說,「整個過程就是:登錄12306->選票->輸驗證碼->錯誤->輸驗證碼->錯誤->輸驗證碼->正確->票沒了。」
  • 12306驗證碼已不再安全 機器準確率99.8%
    12306圖形驗證碼除了拖拽驗證碼,據說難倒了很多購票者的12306的驗證碼其實也可以被破解。12306的驗證碼本質上在做圖片中的對象識別,因此可以利用已經相當成熟的ImageNet相關算法,而ImageNet相關算法對圖片中的實體識別已經到達很高的準確率。谷歌圖形驗證碼此外,就連谷歌圖片驗證碼也可以通過類似的方法被破解。
  • 網購火車票超八成無需驗證碼 只隨機出現
    中國鐵路總公司表示,今年春運網絡購票需要驗證碼的比例將被壓縮到15%以下。昨天,老牌搶票軟體360瀏覽器表示通過大數據分析,今年春運搶票初期,12306的圖形驗證碼並沒有比去年增加難度,他們發現圖形驗證碼已經不是鐵路防止黃牛倒票的主要技術手段,鐵路正在通過更加嚴格的實名認證等其他方式來防黃牛,提高了用戶的購票體驗。
  • 用Python 實現手機自動答題,這下百萬答題遊戲誰也玩不過我!
    但是有時候就會想,能不能實現手機自動答題呢,畢竟網絡上是充斥著很多問題的答案,自己手動搜題速度顯然來不及。答案是當然可以,今天我們就來用手機連接電腦,讓電腦自動搜索答案,省時省力省心。然後藉助ADB實現對手機的調控,包括點觸、滑動、截圖等等功能。2、 讓電腦能夠看懂文字,必然需要對手機屏幕截圖,然後對截圖中的文字識別即可3、 讓電腦操控瀏覽器搜題,用python的庫即可實現了解了整體思路後,下面開始我們的實驗。
  • 利用Python來識別並提取圖片中文字
    文字識別是利用計算機自動識別字符的技術,是模式識別應用的一個重要領域。文字識別一般包括文字信息的採集、信息的分析與處理、信息的分類判別等幾個部分。文字識別可應用於許多領域,如閱讀、翻譯、文獻資料的檢索、信件和包裹的分揀、稿件的編輯和校對、大量統計報表和卡片的匯總與分析、銀行支票的處理、商品發票的統計匯總、商品編碼的識別、商品倉庫的管理,以及水、電、煤氣、房租、人身保險等費用的徵收業務中的大量信用卡片的自動處理和辦公室打字員工作的局部自動化等。以及文檔檢索,各類證件識別,方便用戶快速錄入信息,提高各行各業的工作效率。
  • 用Python 實現手機自動答題,這下百萬答題遊戲誰也玩不過我
    但是有時候就會想,能不能實現手機自動答題呢,畢竟網絡上是充斥著很多問題的答案,自己手動搜題速度顯然來不及。答案是當然可以,今天我們就來用手機連接電腦,讓電腦自動搜索答案,省時省力省心。然後藉助ADB實現對手機的調控,包括點觸、滑動、截圖等等功能。2、 讓電腦能夠看懂文字,必然需要對手機屏幕截圖,然後對截圖中的文字識別即可3、 讓電腦操控瀏覽器搜題,用python的庫即可實現了解了整體思路後,下面開始我們的實驗。