【云计算】图形验证码识别和极验验证码识别区别
小标 2018-12-24 来源 : 阅读 842 评论 0

摘要:本文主要向大家介绍了【云计算】图形验证码识别和极验验证码识别区别,通过具体的内容向大家展现,希望对大家学习云计算有所帮助。

本文主要向大家介绍了【云计算】图形验证码识别和极验验证码识别区别,通过具体的内容向大家展现,希望对大家学习云计算有所帮助。

图形验证码的识别


目标


以知网的验证码为例,讲解利用 OCR 技术识别图形验证码的方法。


准备工作


识别图形验证码需要库 tesserocr。


Linux下的安装:


Ubuntu、 Debian 和 Deepin


在 Ubuntu 、Debian 和 Deepin 系统下,安装命令如下:


sudo apt-get install -y tesseract-ocr libtesseract-dev libleptonica-dev


CentOS 、 Red Hat


在 CentOS 和 Red Hat 系统下 ,安装命令如下 :


yum install -y tesseract


Ubuntu、Debian、Deepin {#ubuntu、debian、deepin}



git clone https://github.com/tesseract-ocr/tessdata.git

sudo mv tessdata/* /usr/share/tesseract-ocr/tessdata


CentOS、RedHat



git clone https://github.com/tesseract-ocr/tessdata.git

sudo mv tessdata/* /usr/share/tesseract/tessdata


这样就可以将下载下来的语言包全部安装了。


这时我们重新运行列出所有语言的命令:



tesseract --list-langs


接下来pip安装tesserocr



pip3 install tesserocr pillow


步骤


1.获取验证码


打开这个链接 //my.cnki.net/elibregister/CheckCode.aspx ,就可以看到一个验证码,右键保存即可,将其命名为 code.jpg。


2.识别测试



import tesserocr

from PIL import Image

image = Image.open('/home/yufeng/Desktop/spider/images/code.jpg')

result = tesserocr.image_to_text(image)

print(result)


通过上面的代码结果显示即为验证码。


另外,tesserocr 还有一个更加简单的方法,这个方法可直接将图片文件转为字符串,代码如下所示 :



import tesserocr

print(tesserocr.file_to_text('image.png'))


不过, 此种方法的识别效果不如上一种方法好。


3.验证码处理


在有偏差的情况下,可以对图片进行转灰度,二值化等操作:



import tesserocr

from PIL import Image

image = Image.open('/home/yufeng/Desktop/spider/images/code.jpg')

image = image.convert('L')#传入参数L可以将图像转化为灰度图像

threshold = 127 #指定二值化阙值,默认阙值为127

table = []

for i in range(256):

if i < threshold:

table.append(0)

else:

table.append(1)



image = image.point(table, '1')#传入参数1将图片进行二值化处理

image.show()



result = tesserocr.image_to_text(image)

print(result)


极验滑动验证码的识别


目标


用程序来识别并通过极验验证码的验证,包括分析识别思路、识别缺 口位置、生成


滑块拖动路径、模拟实现滑块拼合通过验证等步骤。


准备工作


安装Selenium库,Chrome 浏览器,并配置 ChromeDriver。


步骤


1.了解极验验证码


极验验证码官网为: //www.geetest.com/。 它是一个专注于提供验证安全的系统,主要验证方式是拖动滑块拼合图像 。 若图像完全拼合, 则验证成功,即表单成功提交 , 否则需要重新验证。


2.识别思路


参考资料:


网络爬虫实战,崔庆才著


https://blog.csdn.net/coolcooljob/article/details/80400771


首先,模拟点击验证按钮,然后识别活动缺口的位置,最后,模拟拖动滑块。


第一步,我们可以直接利用selienium模拟点击按钮。


第二步,需要用到图像的相关处理方法。实现一个边缘检测算法来找出缺口的位置,而对于这种极验验证码,我们可以利用和原图对比检测的方式来识别缺口的位置,因为在没有滑动滑块之前,缺口并没有呈现。我们可以同时获取两张图片。设定一个 对比阈值,然后遍历两张图片,找出相同位置像素RGB差距超过此阈值的像素点,那么此像素点的位置就是缺口的位置。


第三步,其中的坑比较多。极验验证码增加了机器轨迹识别,匀速运动,随机速度等方法都不能通过验证,只有完全模拟人的移动轨迹才可以通过验证。人的运动轨迹一般是先急加速再减速,我们需要模拟这个过程才能成功。


3.实现


有了思路,我们就可以开始用程序来实现它了。大的方面,主要包括这几个步骤。第一步,初始化,在这里我们先初始化 一些selenium的 配置及一些参数的配置。第二步,就是模拟点击了,这里主要是利用selenium模块模拟浏览器对网页进行操作。


第三步,就该识别缺口的位置了。首先获取前后两张图片,得到其所在位置和宽高,然后获取整个网页的截图,图片裁切下来即可。最后一步,模拟拖动,经过多次试验,得出一个结论,那就是完全模拟加速减速的过程通过了验证。前段作匀加速,后段作匀减速运动,利用物理学的加速度公式即可完成验证。


'''


极验验证码特点:首先点击按钮进行智能验证,如果验证不通过,则会弹出滑动验证的窗口,拖动滑块拼合图像进行验证,之后生成三个加密


参数,通过表单提交到后台,后台还会进行一次验证。


识别验证需要三步:


1.模拟点击验证按钮


2.识别滑动缺口的位置


3.模拟拖动滑块



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 = 'test@qq.com'   #此处填写自己的账号
PASSWORD = ''           #此处填写自己的密码
BORDER = 6
INIT_LEFT = 60


class CrackGeetest():
    def __init__(self):
        self.url = 'https://account.geetest.com/login'
        self.browser = webdriver.Chrome()
        self.wait = WebDriverWait(self.browser, 20)
        self.email = EMAIL
        self.password = PASSWORD
    
    def __del__(self):
        self.browser.close()
    
    def get_geetest_button(self):
        """
        获取初始验证按钮
        :return:
        """
        button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_radar_tip')))
        return button
    
    def get_position(self):
        """
        获取验证码位置
        :return: 验证码位置元组
        """
        img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_canvas_img')))
        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_screenshot(self):
        """
        获取网页截图
        :return: 截图对象
        """
        screenshot = self.browser.get_screenshot_as_png()
        screenshot = Image.open(BytesIO(screenshot))
        return screenshot
    
    def get_slider(self):
        """
        获取滑块
        :return: 滑块对象
        """
        slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_slider_button')))
        return slider
    
    def get_geetest_image(self, name='captcha.png'):
        """
        获取验证码图片
        :return: 图片对象
        """
        top, bottom, left, right = self.get_position()
        print('验证码位置', top, bottom, left, right)
        screenshot = self.get_screenshot()
        captcha = screenshot.crop((left, top, right, bottom))
        captcha.save(name)
        return captcha
    
    def open(self):
        """
        打开网页输入用户名密码
        :return: None
        """
        self.browser.get(self.url)
        email = self.wait.until(EC.presence_of_element_located((By.ID, 'email')))
        password = self.wait.until(EC.presence_of_element_located((By.ID, 'password')))
        email.send_keys(self.email)
        password.send_keys(self.password)
    
    def get_gap(self, 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 self.is_pixel_equal(image1, image2, i, j):
                    left = i
                    return left
        return left
    
    def is_pixel_equal(self, 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_track(self, 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:
                # 加速度为负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:
        """
        ActionChains(self.browser).click_and_hold(slider).perform()
        for x in track:
            ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform()
        time.sleep(0.5)
        ActionChains(self.browser).release().perform()
    
    def login(self):
        """
        登录
        :return: None
        """
        submit = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'login-btn')))
        submit.click()
        time.sleep(10)
        print('登录成功')
    
    def crack(self):
        # 输入用户名密码
        self.open()
        # 点击验证按钮
        button = self.get_geetest_button()
        button.click()
        # 获取验证码图片
        image1 = self.get_geetest_image('captcha1.png')
        # 点按呼出缺口
        slider = self.get_slider()
        slider.click()
        # 获取带缺口的验证码图片
        image2 = self.get_geetest_image('captcha2.png')
        # 获取缺口位置
        gap = self.get_gap(image1, image2)
        print('缺口位置', gap)
        # 减去缺口位移
        gap -= BORDER
        # 获取移动轨迹
        track = self.get_track(gap)
        print('滑动轨迹', track)
        # 拖动滑块
        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()


if __name__ == '__main__':
    crack = CrackGeetest()
    crack.crack()


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标大数据云计算大数据安全频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程