python selenium識別驗證碼並登入

python selenium識別驗證碼並登入

由於工作需要,登入網站需要用到驗證碼。最初是研究過驗證碼識別的,但是總是不能獲取到我需要的那個驗證碼。直到這週五,才想起這事來,昨天順利的解決了。

下面正題:

python版本:3.4.3

所需要的程式碼庫:PIL,selenium,tesseract

先上程式碼:

#coding:utf-8
import subprocess
from PIL import Image
from PIL import ImageOps
from selenium import webdriver
import time,os,sys

def cleanImage(imagePath):
    image = Image.open(imagePath)   #開啟圖片
    image = image.point(lambda x: 0 if x<143 else 255)  #處理圖片上的每個畫素點,使圖片上每個點“非黑即白”
    borderImage = ImageOps.expand(image,border=20,fill=’white’)
    borderImage.save(imagePath)

def getAuthCode(driver, url=”http://localhost/”):
    captchaUrl = url “common/random”
    driver.get(captchaUrl)  
    time.sleep(0.5)
    driver.save_screenshot(“captcha.jpg”)   #截圖,並儲存圖片
    #urlretrieve(captchaUrl, “captcha.jpg”)
    time.sleep(0.5)
    cleanImage(“captcha.jpg”)
    p = subprocess.Popen([“tesseract”, “captcha.jpg”, “captcha”], stdout=\
                         subprocess.PIPE,stderr=subprocess.PIPE)
    p.wait()
    f = open(“captcha.txt”, “r”)
    
    #Clean any whitespace characters
    captchaResponse = f.read().replace(” “, “”).replace(“\n”, “”)

    print(“Captcha solution attempt: ” captchaResponse)
    if len(captchaResponse) == 4:
        return captchaResponse
    else:
        return False

def withoutCookieLogin(url=”http://org.cfu666.com/”):
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get(url)
    while True:      
        authCode = getAuthCode(driver, url)
        if authCode:
            driver.back()
            driver.find_element_by_xpath(“//input[@id=’orgCode’ and @name=’orgCode’]”).clear()
            driver.find_element_by_xpath(“//input[@id=’orgCode’ and @name=’orgCode’]”).send_keys(“orgCode”)
            driver.find_element_by_xpath(“//input[@id=’account’ and @name=’username’]”).clear()
            driver.find_element_by_xpath(“//input[@id=’account’ and @name=’username’]”).send_keys(“username”)
            driver.find_element_by_xpath(“//input[@type=’password’ and @name=’password’]”).clear()
            driver.find_element_by_xpath(“//input[@type=’password’ and @name=’password’]”).send_keys(“password”)              
            driver.find_element_by_xpath(“//input[@type=’text’ and @name=’authCode’]”).send_keys(authCode)
            driver.find_element_by_xpath(“//button[@type=’submit’]”).click()
            try:
                time.sleep(3)
                driver.find_element_by_xpath(“//*[@id=’side-menu’]/li[2]/ul/li/a”).click()
                return driver
            except:
                print(“authCode Error:”, authCode)
                driver.refresh()
    return driver

driver = withoutCookieLogin(“http://localhost/”)
driver.get(“http://localhost/enterprise/add/”)

怎麼獲取我們需要的驗證碼

在這獲取驗證碼的道路上,我掉了太多的坑,看過太多的文章,很多都是教你驗證碼的識別方法,但是沒有說明,怎麼獲取你當前需要的驗證碼圖片。

我的處理方法是:

1.先用selenium開啟你需要的登入的頁面地址url1

2.通過稽核元素獲取驗證碼的地址url2(其實最簡單的是右鍵開啟新頁面)

3:在url1頁面,輸入地址url2進入url2頁面,然後截圖儲存驗證碼頁面

4:處理驗證碼得到驗證碼字串。然後點選瀏覽器後退按鈕,返回url1登入頁面

5:輸入登入需要的資訊和驗證碼

6:點選登入

7:驗證登入後的頁面,判斷是否成功,若不成功則需要重新1-7的操作。

為了保護公司的資訊,這個頁面是我本地搭的服務,我在伯樂線上註冊頁面進行測試過這個驗證碼獲得方法,可以通過。(這個驗證碼的處理方法,僅限驗證碼背景是畫素點,若驗證碼有橫線需額外處理。)

第一篇博文,不喜勿噴。

驗證碼處理方法參考文獻:

Web Scraping with Python.pdf