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)后面的处理过程与思路一的图片处理方法相同。
以上是 python + selenium获取验证码 的全部内容, 来源链接: utcz.com/z/386565.html