验证码识别
warning:
这篇文章距离上次修改已过765天,其中的内容可能已经有所变动。
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ActionChains
from PIL import Image
#https://www.om.cn/register
Email='test@test.com'
PASSWORD='123456'
url='https://auth.geetest.com/login/'
driver=webdriver.Chrome()
wait=WebDriverWait(driver,20)
driver.get(url)
email=Email
password=PASSWORD
def get_geetest_button():
'''
获取初始验证按钮
:return: 按钮对象
'''
button=wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'geetest_btn_click')))
return button
def get_position():
'''
获取验证码位置
:return: 验证码位置元组
'''
img=wait.until(EC.presence_of_element_located((By.CLASS_NAME,'geetest_bg')))
time.sleep(2)
location=img.location
size=img.size
top,bottom,left,right=location['y'],location['y']+size['height'],location['x'],location['x']+size['width']
return (top,bottom,left,right)
def get_geetest_image():
'''
获取验证码图片
:return: 图片对象
'''
top, bottom, left, right=get_position()
print('验证码位置:',top,bottom,left,right)
screenshot=driver.get_screenshot_as_png()
captcha=screenshot.crop((top,bottom,left,right))
return captcha
def slider():
'''
获取滑块
:return:滑块对象
'''
slider=wait.until(EC.element_to_be_clickable(By.CLASS_NAME,'geetest_arrow'))
return slider
def is_pixel_equal(image1,image2,x,y):
'''
判断像素是否相同
:param image1: 图片1
:param image2: 图片2
:param x: 位置x
:param y: 位置y
:return: 像素是否相同
'''
#取两个像素点
pixel1=image1.load()[x,y]
pixel2=image2.load()[x,y]
threshold=60
if abs(pixel1[0]-pixel2[0])<threshold and abs(pixel1[1]-pixel2[1])<threshold and abs(pixel1[2]-pixel2[2])<threshold:
return True
else:
return False
def get_gap(image1,image2):
'''
获取缺口偏移量
:param image1: 不带缺口图片
:param image2: 带缺口图片
:return: 偏移量
'''
left=60
for i in range(left,image1.size[0]):
for j in range(image1.size[1]):
if not is_pixel_equal(image1,image2,i,j):
left=i
return left
return left
def get_track(distance):
'''
根据偏移量获取移动轨迹
:param distance: 偏移量
:return: 移动轨迹
'''
#移动轨迹
track=[]
#当前位移
current=0
#减速阈值
mid=distance*4/5
#计算间隔
t=0.2
v=0 #初速度
while current < distance:
if current<mid:
#加速度为2
a=2
else:
a=-3
#初速度v0
v0=v
#当前速度v=v0+at
v=v0+a*t
#移动距离x=v0*t+1/2*a*t*t
move = v0 * t + 1 / 2 * a * t * t
#当前位移
current+=move
#加入轨迹
track.append(round(move))
return track
def move_to_gap(slider,tracks):
'''
拖动到滑块缺口处
:param slider: 滑块
:param tracks: 轨迹
:return:
'''
ActionChains(driver).click_and_hold(slider).perform()
for x in tracks:
ActionChains(driver).move_by_offset(xoffset=x,yoffset=0).perform()
time.sleep(0.5)
ActionChains(driver).release().perform()
button=get_geetest_button()
button.click()