本文主要是解决验证码截图偏移问题
如下便是我编写的关于识别网址验证码的位置的代码
#coding:utf-8
from selenium import webdriver
import random
import tesserocr
import re
import requests
import pytesseract
from selenium import webdriver
from PIL import Image, ImageEnhance,ImageGrab
import os
import time
from pytesser3 import *
def loginWeb(urlAddr):
#模拟验证码
'''
#chrome驱动
chromedriver = "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe" # 这里写本地的chromedriver 的所在路径
os.environ["webdriver.Chrome.driver"] = chromedriver # 调用chrome浏览器
options = webdriver.ChromeOptions()
options.add_argument(
'user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36"')
driver = webdriver.Chrome(chromedriver, chrome_options=options)
'''
#firefox驱动
options = webdriver.FirefoxOptions()
options.add_argument(
'user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36"')
driver = webdriver.Firefox(firefox_options=options,executable_path='./geckodriver.exe')
driver.get(urlAddr) # 该处为具体网址
driver.refresh() # 刷新页面
#driver.maximize_window() # 浏览器最大化
driver.set_window_size(1280, 1024)
width_driver = driver.get_window_size()['width']
# 获取全屏图片,并截取验证码图片的位置
driver.get_screenshot_as_file('a.png')
imgelement = driver.find_element_by_xpath("//div[@id='Main']/div[2]/div[3]/form/table/tbody/tr[3]/td[2]/div")
location = imgelement.location
size = imgelement.size
rangle = (int(location['x']), int(location['y']), int(location['x'] + size['width']),int(location['y'] + size['height']))
im = Image.open('a.png')
im = im.crop(rangle)
im.save('a1.png')
# 打开保存的验证码图片
image = Image.open("a1.png")
# 图片转换成字符
vcode = pytesseract.image_to_string(image)
print(vcode)
# 填充用户名 密码 验证码(id替换成实际上的控件元素名称) driver.find_element_by_xpath("//div[@id='Main']/div[2]/div[3]/form/table/tbody/tr/td[2]/input").send_keys("username") driver.find_element_by_xpath("//div[@id='Main']/div[2]/div[3]/form/table/tbody/tr[2]/td[2]/input").send_keys("password")
driver.find_element_by_xpath("//div[@id='Main']/div[2]/div[3]/form/table/tbody/tr[3]/td[2]/input").send_keys(vcode)
# 点击登录
driver.find_element_by_xpath("//input[@value='登录']").click()
time.sleep(5)
driver.close()
测试网址为urlAddr =‘https://www.v2ex.com/signin?next=/t/73685’,然而在切割验证码图片上始终都是失败的,切割的位置始终有偏移量
driver.get_screenshot_as_file('a.png')
imgelement = driver.find_element_by_xpath("//div[@id='Main']/div[2]/div[3]/form/table/tbody/tr[3]/td[2]/div")
location = imgelement.location
size = imgelement.size
rangle = (int(location['x']), int(location['y']), int(location['x'] + size['width']),int(location['y'] + size['height']))
im = Image.open('a.png')
im = im.crop(rangle)
im.save('a1.png')
如上代码段就是定位控件元素的位置后,获取其位置并将验证码图片给割下来的逻辑。运行实际结果,验证码并没有准确的定位到。经过反复查找网络上的资料,基本逻辑实现基本上是没有什么不同,但是有个mac操作系统上实现却有所不同。于是我尝试使用PhantomJS,因为这个浏览器在运行时,是没有界面的,所以可以用来确定是不是操作系统的原因导致定位不准确。于是有了下面的测试代码:
def maoyan(urlAddr):
#urlAddr = "http://m.maoyan.com/shows/149?_v_=yes"
'''
options = webdriver.FirefoxOptions()
options.add_argument(
'user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36"')
driver = webdriver.Firefox(firefox_options=options, executable_path='./geckodriver.exe')
'''
# 打开浏览器并访问指定地址
driver = webdriver.PhantomJS(executable_path=r"D:\phantomjs-2.1.1-windows\bin\phantomjs.exe")
driver.get(urlAddr)
#driver.refresh() # 刷新页面
#driver.maximize_window() # 浏览器最大化
driver.set_window_size(1366, 768)
# 定位到需要截图的div,或者标签位置。(注:此步骤是为了后续二次截图使用)
imgelement = driver.find_element_by_xpath("//h3[contains(.,'首都电影院(西单店)')]")
# 图片坐标。(注:图片坐标为标签相对整个截图的坐标位置)
locations = imgelement.location
print(locations)
# 图片大小
sizes = imgelement.size
print(sizes)
# 构造指数的位置,计算出需要截图的长宽、高度等
rangle = (int(locations['x']), int(locations['y']), int(locations['x'] + sizes['width']),
int(locations['y'] + sizes['height']))
print(rangle)
driver.save_screenshot( "a.png")
# 打开截图切割,python一个库,尺寸就是上边调好的参数。
img = Image.open("a.png")
jpg = img.crop(rangle)
jpg.save("a1.png")
print("图片截取成功!")
# 图像识别。注:OCR识别的准确度是可以训练的,本图片不存在误差,顾不需要训练
# 但是本教程部分步骤也适用验证码识别,则需要进行图片训练,有兴趣的可以百度一下。
image = Image.open("a1.png")
image.load()
code = pytesseract.image_to_string((image), lang='chi_sim')
print("图片内容识别为:"+code)
# 关闭浏览器
driver.close()
测试网址是"http://m.maoyan.com/shows/149?v=yes"。这个代码段是为了截取下图中的红框字段:
在firefox浏览器的seleniumide插件上,定位元素是正确的,然后我使用了PhantomJS作为selenium的浏览器驱动,经过跟上一个一样的逻辑去测试这个代码。确定了问题是我电脑的原因。
既然已经确定了问题所在,那么再试试之前的验证码页面:
将driver替换成PhantomJS,其余代码不变
#PhantomJS
driver = webdriver.PhantomJS(executable_path=r"D:\phantomjs-2.1.1-windows\bin\phantomjs.exe")
driver.get(urlAddr)
driver.set_window_size(1366, 768)
ok,测试成功。至于验证码的读取,由于这个验证码比较复杂,干扰点比较多,需要二值化,去除干扰点等,可以参考
https://www.cnblogs.com/beer/p/7877570.html
这一篇文章是基于cnn(神经网络)算法,验证码需要提升成功率的话,还是机器学习深度学习比较合适,训练多次,建立模型,成功率就比较高咯。
一般情况下,登陆有验证码的页面,有些人使用cookie来跳过,如果识别验证码成功率高,可以使用while循环,每次读取失败,刷新下,换个验证码再试试。。当然,在输入driver.find_element_by_xpath("//div[@id=‘Main’]/div[2]/div[3]/form/table/tbody/tr/td[2]/input").send_keys(“username”)
可以添加前置
driver.find_element_by_xpath("//div[@id=‘Main’]/div[2]/div[3]/form/table/tbody/tr/td[2]/input").clear()