![验证码识别
简单的图形验证码识别
极验滑动验证码的识别https://www.geetest.com/show]()
![验证码识别
简单的图形验证码识别
极验滑动验证码的识别https://www.geetest.com/show]()
import time
from io import BytesIO
from PIL import Image
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
EMAIL = 'zcs@163.com'
PASSWORD = '123'
BORDER = 6
class CrackGeetest():
def __init__(self):
self.url = 'https://account.geetest.com/login'
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser, 10)
self.email = EMAIL
self.password = PASSWORD
# 当需要删除对象来释放类所占用的资源的时候,就需要调用析构方法__del__()。
def __del__(self):
self.browser.close()
def open_url(self):
"""
打开网页输入用户名密码
:return: None
"""
self.browser.get(self.url)
email = self.wait.until(
EC.presence_of_element_located(
(By.ID, 'ivu-form-item.ivu-form-item-required.ivu-form-item-error .ivu-input')
)
)
password = self.wait.until(
EC.presence_of_element_located(
(By.ID, '.ivu-input.ivu-input-has-value')
)
)
email.send_keys(self.email)
password.send_keys(self.password)
def get_button(self):
"""
获取验证按钮
:return:
"""
button = self.wait.until(
EC.element_to_be_clickable(
(By.CLASS_NAME, 'geetest_radar_tip')
)
)
return button
def get_slider(self):
"""
获取滑块
:return: 滑块对象
"""
slider = self.wait.until(
EC.element_to_be_clickable(
(By.CLASS_NAME, 'geetest_slider_button')
)
)
return slider
def get_image(self):
"""
获取验证码图片
:return: 图片对象(无缺口图像和有缺口图像)
"""
return 1, 2
def get_distance(self, image1, image2):
"""
获取缺口距离
:param image1: 无缺口的滑动验证码图片
:param image2: 有缺口的滑动验证码图片
:return:
"""
left = 60
# 根据滑块的像素为 60 ,选择 60 像素为起始点
threhold = 70
# 阈值为 70
for i in range(left, image1.size[0]):
# 遍历 image1 的 left ~~ 最右端
for j in range(image1.size[1]):
# 遍历 image1 的高
rgb1 = image1.load()[i, j]
rgb2 = image2.load()[i, j]
res1 = abs(rgb1[0] - rgb2[0])
res2 = abs(rgb1[1] - rgb2[1])
res3 = abs(rgb1[2] - rgb2[2])
if not (res1 < threhold and res2 < threhold and res3 < threhold):
return i
# image1 和 image2 同一位置的 RGB差值 是否在阈值之内。假如不在,则为缺口位置
return left
def get_track(self, distance):
"""
根据偏移量获取移动轨迹
:param distance: 偏移量
:return: 移动轨迹
"""
# 移动轨迹
track = []
# 当前位移
current = 0
# 减速阈值
mid = distance * 4 / 5
# 计算间隔
t = 0.2
# 初速度
v = 0
# 当滑块位移小于缺口距离这时候
while current < distance:
# 滑块位移小于缺口距离的 80% 这时,速度为2;否则速度为-3
if current < mid:
# 加速度为正2
a = 2
else:
# 加速度为负3
a = -3
# 初速度v0
v0 = v
# 当前速度v = v0 + at
v = v0 + a * t
# 移动距离x = v0t + 1/2 * a * t^2
move = v0 * t + 1 / 2 * a * t * t
# 当前位移
current += move
# 加入轨迹
track.append(round(move))
return track
def move_to_gap(self, slider, track):
"""
拖动滑块到缺口处
:param slider: 滑块
:param track: 轨迹
:return:
"""
# 创建新的操作链
action_chains1 = ActionChains(self.browser)
# 按住鼠标左键
down_left_mouse = action_chains1.click_and_hold(slider)
# 执行所有储存的操作
down_left_mouse.perform()
# 遍历轨迹,获取每一小段位移距离
for x in track:
# 创建新的操作链
action_chains2 = ActionChains(self.browser)
# 按住鼠标后移动滑块
move_mouse = action_chains2.move_by_offset(xoffset=x, yoffset=0)
# 执行
move_mouse.perform()
time.sleep(0.5)
# 执行滑块到缺口后,调用release()方法,松开鼠标
ActionChains(self.browser).release().perform()
def login(self):
"""
登录
:return: None
"""
submit = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest-btn')))
submit.click()
time.sleep(10)
print('登录成功')
def crack(self):
# 输入用户名密码
self.open_url()
# 点击验证按钮
button = self.get_button()
button.click()
# 获取验证码图片和带缺口的验证码图片
image1, image2 = self.get_image()
# 获取缺口位置
gap = self.get_distance(image1, image2)
print('缺口位置', gap)
# 减去缺口位移
gap = gap - BORDER
# 获取移动轨迹
track = self.get_track(gap)
print('滑动轨迹', track)
# 拖动滑块
slider = self.get_slider()
self.move_to_gap(slider, track)
success = self.wait.until(
EC.text_to_be_present_in_element((By.CLASS_NAME, 'geetest_success_radar_tip_content'), '验证成功'))
print(success)
# 失败后重试
if not success:
self.crack()
else:
self.login()
def main():
# 调用CrackGeetest()类
crack_geetest = CrackGeetest()
# 输入用户名密码
crack_geetest.open_url()
# 点击验证按钮
button = crack_geetest.get_button()
button.click()
# 获取验证码图片和带缺口的验证码图片
image1, image2 = crack_geetest.get_image()
# 获取缺口位置
gap = crack_geetest.get_distance(image1, image2)
print('缺口位置', gap)
# 减去缺口位移
gap = gap - BORDER
# 获取移动轨迹
track = crack_geetest.get_track(gap)
print('滑动轨迹', track)
# 拖动滑块
slider = crack_geetest.get_slider()
crack_geetest.move_to_gap(slider, track)
success = crack_geetest.wait.until(
EC.text_to_be_present_in_element((By.CLASS_NAME, 'geetest_success_radar_tip_content'), '验证成功'))
print(success)
# 失败后重试
if not success:
main()
else:
crack_geetest.login()
if __name__ == '__main__':
main()
View Code
![验证码识别
简单的图形验证码识别
极验滑动验证码的识别https://www.geetest.com/show]()
![验证码识别
简单的图形验证码识别
极验滑动验证码的识别https://www.geetest.com/show]()
import tesserocr
from PIL import Image
image = Image.open('PFET.jpg')
# 利用 Image 对象的 convert() 方法传入参数 "L" ,即可将图片转化为灰度图像
image = image.convert('L')
# 阈值默认为127
threshold = 127
table = []
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
image = image.point(table, '1')
image = image.convert('1')
image.show()
result = tesserocr.image_to_text(image)
print(result)
# 输出:
PFRT
View Code