python + selenium获取验证码


解决验证码的方法:

方法一:让开发帮忙去掉验证码代码,重新部署环境。(不推荐)

方法二:弄个万能验证码,每次登陆都可以登陆。(不推荐)

方法三:用cookie添加登陆名和密码避开验证码的方式。(我还不会)

方法四:老老实实获取验证码。(重点讲这个)

采用方法四需要引用第三方库:pytesseract,该库依赖于Tesseract,所以需要先安装Tesseract。

1、安装Tesseract模块

     git文档地址:https://digi.bib.uni-mannheim.de/tesseract/    

     请安装不带dev的稳定版,下载后就是一个exe安装包,直接右击安装即可。

2、如果您想使用其他语言,请下载相应的培训数据,直接下载整个zip文件,解压后将文件复制到'tessdata'目录中。C:\Program Files (x86)\Tesseract-OCR\tessdata

3、配置环境变量:    

  (1)编辑系统变量里面 path,添加下面的安装路径:C:\Program Files (x86)\Tesseract-OCR 

  (2)添加TESSDATA_PREFIX变量,值为:C:\Program Files (x86)\Tesseract-OCR\tessdata

  cmd命令模式下测试是否安装成功:
  tesseract test.jpg text -l chi_sim

4、安装python的第三方库:  

  pip install pillow #一个python的图像处理库,pytesseract依赖
  pip install pytesseract

5、找到pytesseract的安装包,C:\Python34\Lib\site-packages\pytesseract,编辑pytesseract.py文件(此步骤必须做,否则运行代码时会报错):

  tesseract_cmd = 'C:/Program Files (x86)/Tesseract-OCR/tesseract.exe'

获取验证码有2种思路:

1、截图登陆页面,再截取验证码图片,识别;

2、直接在登陆页面,定位到验证码,将验证码图片另存为,识别;

思路一具体实现过程:

(1)先计算浏览器与登陆页面截图的比例值,再计算对应的验证码图片位置。不这样做的话,会导致获取的验证码位置不正确。

browser.maximize_window()
    #获取浏览器大小
    size_window = browser.get_window_size()
    time.sleep(1)
    #获取截图
    browser.save_screenshot('login.png')
    login_img = Image.open('login.png')
    (login_width,login_height) = login_img.size
    logger.info('截图的宽高:')
    logger.info(login_width,login_height)
    #计算浏览器与截图比例
    scale = size_window['width'] / login_width
    #获取验证码
    code_loc = browser.find_element_by_xpath('//*[@id="valiCode"]').location
    code_size = browser.find_element_by_xpath('//*[@id="valiCode"]').size    
    #获取验证码位置
    #此处的X和Y分别加了数字,因为前端的样式中,验证码标签img的margin-left为15,margin-top为5
    location_X = math.ceil(code_loc['x'] / scale) + 15
    location_Y = math.ceil(code_loc['y'] / scale) + 5
    location_height = math.ceil(code_size['height'] / scale)
    location_width = math.ceil(code_size['width'] / scale)

    code_img = login_img.crop((location_X,location_Y,location_X + location_width ,location_Y + location_height))
    code_img.save('code.png')

 (2)再将获取到的验证码图片,先进行二值化处理,以便提取验证码更容易,这里涉及一些图像处理的算法。

#先二值化处理  
    image=Image.open(img)  
    # 灰度图  
    lim=image.convert('L')  
    # 灰度阈值设为100,低于这个值的点全部填白色  
    threshold=100
    table=[]  
      
    for j in range(256):  
        if j<threshold:  
            table.append(0)  
        else:  
            table.append(1)  
  
    bim=lim.point(table,'1')  
    bim.save('newImg.png') 

(3)处理后的图像更容易获取验证码,这里采用pytesseract库转化,注意后面的参数设置。

先前不设置参数时,总是将1转化为7,设置后转化的准确率杠杠滴。

当然,目前只是识别数字型的验证码,文字类型的方法应该是类似的。

lastpic = Image.open('newImg.png')
    text = pytesseract.image_to_string(lastpic,lang='eng',config='--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789').strip()
    #后面的配置简直是神器啊,之前一直将1读成7,加配置后很准确
    with open('output.txt','w') as f:
        f.write(text)
    with open('output.txt','r') as f:
        code = f.read() 
    f.close()
    logger.info("获取的验证码为:")
    logger.info(code)

思路二具体实现过程:

(1)先定位到登陆页面中验证码的位置,将验证码图片另存到一个路径下,并且返回最新时间保存的图片。

# 把验证码另存为图片
def image_save_as():
    image = driver.find_element_by_id("valiCode")
    actions = ActionChains(driver)
    actions.context_click(image)
    actions.perform()
    pyautogui.typewrite(['down', 'down', 'enter', 'enter']) # 右键找到图片另存为
    sleep(2)
    pyautogui.typewrite(['enter'])
    sleep(2)

def get_newest_image(image_path):

    lists = os.listdir(image_path)
    lists.sort(key=lambda fn:os.path.getmtime(image_path + "\\" + fn))  # 按时间排序
    image_new = os.path.join(image_path, lists[-1])

    return image_new

(2)后面的处理过程与思路一的图片处理方法相同。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM