python 識別驗證碼自動登陸


 

# python 3.5.0
# 通過Chrom瀏覽器訪問發起請求
# 需要對應版本的Chrom和chromdriver 
# 作者:linyouyi

from selenium import webdriver
# 引入Keys類包 發起鍵盤操作
from selenium.webdriver.common.keys import Keys
import threading
import time
import random
import requests
import eventlet
import _thread
from io import BytesIO
from PIL import Image
from PIL import ImageEnhance
import pytesseract
import re
pytesseract.pytesseract.tesseract_cmd = 'D:\\Program Files\\Tesseract-OCR\\tesseract.exe'
tessdata_dir_config = '--tessdata-dir "D:\\Program Files\\Tesseract-OCR\\tessdata"'

def chrome():
    print("啟動第一個線程==============================")
    chromeOptions = webdriver.ChromeOptions()
    #chromeOptions.add_argument('user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1"')
    chrome_driver="C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"
    #chromeOptions.add_argument("--headless")
    chromeOptions.add_argument("--disable-gpu")
    #下面兩行是禁止加載圖片,提高速度
    #prefs = {"profile.managed_default_content_settings.images":2}
    #chromeOptions.add_experimental_option("prefs",prefs)

    driver = webdriver.Chrome(chrome_options=chromeOptions,executable_path=chrome_driver)
    return driver
    
def read_file(filedir):
    '''讀取鏈接文件'''
    file = open(filedir,'r')
    return file
    
def send_massage(filedir):
    '''一次返回一個鏈接'''
    file = read_file(filedir)
    for line in file:
        # 生成器,一次返回一項
        yield line
    file.close()
    
def binaryzation(code_image,value):
    '''二值化處理'''
    #轉換成灰度
    im = code_image.convert('L')
    #對比度增強 
    im = ImageEnhance.Contrast(im)
    im = im.enhance(1)
    #銳度增強
    #im=ImageEnhance.Sharpness(im)
    #im=im.enhance(3.0)
    #色度增強
    #im=ImageEnhance.Color(im)
    #im=im.enhance(3.0)
    #亮度增強  
    #im=ImageEnhance.Brightness(im)
    #im=im.enhance(2.0)
    
    table = []
    for y in range(256):
        if y < value:
            table.append(0)
        else:
            table.append(1)
    im = im.point(table,'1')
    return im
    
def discern(code_img):
    '''識別驗證碼'''
    try:
        im = binaryzation(code_img,127)
        code = pytesseract.image_to_string(im)
        # 保留數字和字母
        code = re.sub("\W", "", code)
        if code == '':
            return "6666"
        else:
            return code
    except:
        return "識別驗證碼失敗!!!"
    

    
def call_link(filedir):
    '''在所有input填入手機號碼,獲取驗證碼圖片,識別完輸入驗證碼'''
    driver = chrome()
    link = send_massage(filedir)
    for link in link:
        print(link)
        try:
            # 超時則跳過
            eventlet.monkey_patch()
            with eventlet.Timeout(100,False):
                # 訪問鏈接
                driver.get(link)
                # 最多等待10秒
                driver.implicitly_wait(10)
                button = driver.find_elements_by_xpath('//button')
                span = driver.find_elements_by_xpath('//span')
                inp = driver.find_elements_by_xpath('//div//input')
                '''# 所有input都填上手機號碼
                for aa in inp:
                    try:
                        aa.send_keys('00000000000')
                        time.sleep(random.randint(1,2))
                    except:
                        print("########")'''
                time.sleep(5)
                # 獲取所有圖片標簽
                images = driver.find_elements_by_xpath('//img')
                for img in images:
                    img_link = img.get_attribute("src")
                    if ("captcha" in img_link):
                        print(img_link)
                        # 獲取驗證碼在畫布中的位置x,y軸坐標
                        img_location = img.location
                        # 獲取驗證碼大小
                        img_size = img.size
                        # 截取的是整個屏幕
                        code_img = driver.get_screenshot_as_png()
                        # 截圖保存
                        #driver.get_screenshot_as_file('D:\\pythontest\\duanxinhongzha\\aa.png')
                        code_img = Image.open(BytesIO(code_img))
                        # 使用Image的crop函數,從截圖中再次截取我們需要的驗證碼所在區域
                        code_img = code_img.crop((img_location['x'],img_location['y'],int(img_location['x'] + img_size['width']),int(img_location['y'] + img_size['height'])))
                        # 圖片放大兩倍
                        code_img = code_img.resize((img_size['width'] * 2,img_size['height'] * 2))
                        #code_img.save('D:\\pythontest\\duanxinhongzha\\aa.png')
                        print("驗證碼所在區域大小為:", code_img.size)
                        # 把識別的驗證碼填入,如果識別不出來擇忽略錯誤
                        code_num = discern(code_img)
                        print(code_num)
                        # 根據條件輸入驗證碼,不符合條件的input都填上手機號碼
                        for inp_num in inp:
                            try:
                                if ("captcha" in inp_num.get_attribute('id').lower() ):
                                    inp_num.send_keys(code_num)
                                elif ("ode" in inp_num.get_attribute('id').lower()):
                                    inp_num.send_keys(code_num)
                                elif ("captcha" in inp_num.get_attribute('name').lower()):
                                    inp_num.send_keys(code_num)
                                else:
                                    inp_num.send_keys('00000000000')
                                    time.sleep(random.randint(1,2))
                            except:
                                print("########")
                        
                # 如果按鈕是a標簽形式,則獲取然后點擊
                try:
                    driver.find_element_by_partial_link_text("獲取").click()
                except:
                    print("a標簽失敗")
                # 如果按鈕是button標簽形式,則獲取然后點擊
                try:
                    
                    for button in button:
                        if ("獲取" in button.text or "發送" in button.text or "" in button.text):
                            button.click()
                except:
                    print("button失敗!!!")
                # 如果按鈕是span標簽形式,則獲取然后點擊
                try:
                    for span in span:
                        if ("獲取" in span.text or "發送" in span.text or "" in span.text):
                            span.click()
                except:
                    print("span失敗!!!")
                # 如果按鈕是input標簽形式,則獲取然后點擊
                try:
                    for inp in inp:
                        if ("獲取" in inp.get_attribute("value") or "發送" in inp.get_attribute("value") or "" in inp.get_attribute("value")):
                            inp.click()
                except:
                    print("input失敗!!!")
                #driver.find_element_by_partial_link_text(str(u"獲取").encode('utf-8')).send_keys(Keys.ENTER)
                #driver.find_element_by_partial_link_text('獲取').find_element().click()
                print("短信發送完畢!!!!")
                time.sleep(5)
                
        except:
            print("獲取文本失敗!!!")
    driver.quit()
    
    

if __name__ == '__main__':
    #t1 = threading.Thread(target=query_register)
    #t2 = threading.Thread(target=button)
    t3 = threading.Thread(target=call_link('D:\pythontest\lianjie1.txt'))
    
    #t1.start()
    #t2.start()
    t3.start()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM