文字点选验证码的破解方法~

简介: 大家好,我是志斌~志斌之前一直在写反爬虫系列的文章,但是因为自身水平有限,所以一直没更验证码反爬虫之文字点选验证码反爬虫的解决方式,这次专门为大家找了一个大佬——张老师,来跟大家分享一下他解决文字点选验证码的方法~

基本思路


  1. 获取图像
  2. 对图像进行二值化处理
  3. 识别图中轮廓
  4. 识别轮廓文字
  5. 构建待选文字图像
  6. 比较识别文字与待选文字图像
  7. 返回点选结果

本文仅提供基本思路,具体应用需根据各类型点选验证码自行修改。



实现过程


0.导入依赖


import base64
import json
import cv2
import numpy as np
import requests
from PIL import Image, ImageDraw, ImageFont


  1. 获取图像

第一步是获取图像,有一些验证码图像是以二进制形式返回的,本文测试的图像是以base64编码字符串的形式返回,因此需要对其进行解码。


def getData(capsession: requests.Session):
    resp = s.post("验证码获取url")
    return resp.json()["repData"]
def getImageFromBase64(b64):
    buffer = base64.b64decode(b64)
    nparr = np.frombuffer(buffer, np.uint8)
    image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
    return image


2.对图像进行二值化处理

为了方便识别文字轮廓,我们对图像进行二值化处理。


def normalizeImage(img):
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, img = cv2.threshold(img, 1, 255, cv2.THRESH_BINARY)
    img = cv2.bitwise_not(img)
    return img


3.识别图中轮廓

在识别图中轮廓时,为了提高效率和准确度,我们对轮廓按长宽比和面积进行筛选,尽可能保证轮廓能够满足文字识别需要。


def findContour(img):
    contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL,
                                   cv2.CHAIN_APPROX_SIMPLE)
    def find_if_close(cnt1, cnt2):
        row1, row2 = cnt1.shape[0], cnt2.shape[0]
        for i in range(row1):
            for j in range(row2):
                dist = np.linalg.norm(cnt1[i] - cnt2[j])
                if abs(dist) < 5:
                    returnTrue
                elif i == row1 - 1and j == row2 - 1:
                    returnFalse
    LENGTH = len(contours)
    status = np.zeros((LENGTH, 1))
    for i, cnt1 in enumerate(contours):
        x = i
        if i != LENGTH - 1:
            for j, cnt2 in enumerate(contours[i + 1:]):
                x = x + 1
                dist = find_if_close(cnt1, cnt2)
                if dist == True:
                    val = min(status[i], status[x])
                    status[x] = status[i] = val
                else:
                    if status[x] == status[i]:
                        status[x] = i + 1
    unified = []
    maximum = int(status.max()) + 1
    for i in range(maximum):
        pos = np.where(status == i)[0]
        if pos.size != 0:
            cont = np.vstack([contours[i] for i in pos])
            hull = cv2.convexHull(cont)
            unified.append(hull)
    cnt = list(filter(aspectRatio,unified))
    cnt.sort(key=cv2.contourArea,reverse=True)
    return cnt[:4]
def aspectRatio(cnt):
    _,_,w,h = cv2.boundingRect(cnt)
    return (0.6<float(w)/h<1.7) and (cv2.contourArea(cnt)>200.0)


4.识别轮廓文字

我们对图中文字轮廓进行识别,返回文字轮廓与相应的坐标位置。


def extractCharContour(img, contour):
    mult = 1.2
    ret = []
    point = []
    for cnt in contour:
        rect = cv2.minAreaRect(cnt)
        box = cv2.boxPoints(rect)
        box = np.int0(box)
        W = rect[1][0]
        H = rect[1][1]
        Xs = [i[0] for i in box]
        Ys = [i[1] for i in box]
        x1 = min(Xs)
        x2 = max(Xs)
        y1 = min(Ys)
        y2 = max(Ys)
        rotated = False
        angle = rect[2]
        if angle < -45:
            angle += 90
            rotated = True
        center = (int((x1 + x2) / 2), int((y1 + y2) / 2))
        size = (int(mult * (x2 - x1)), int(mult * (y2 - y1)))
        try:
            M = cv2.getRotationMatrix2D((size[0] / 2, size[1] / 2), angle,
                                        1.0)
            cropped = cv2.getRectSubPix(img, size, center)
            cropped = cv2.warpAffine(cropped, M, size)
            croppedW = W ifnot rotated else H
            croppedH = H ifnot rotated else W
            croppedRotated = cv2.getRectSubPix(
                    cropped,
                    (int(croppedW * mult), int(croppedH * mult)),
                    (size[0] / 2, size[1] / 2),
            )
            im = cv2.resize(croppedRotated, (20, 20))
            kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]],
                                  np.float32)
            im = cv2.filter2D(im, -1, kernel=kernel)
            ret.append(im)
            point.append((rect[0][0], rect[0][1]))
        except:
            pass
    return ret, point


5.构建待选文字图像

将获取的待选文字转化为图像。


def genCharacter(ch, size):
    img = Image.new("L", size, 0)
    font = ImageFont.truetype("simsun.ttc", min(size))
    draw = ImageDraw.Draw(img)
    draw.text((0, 0), ch, font=font, fill=255)
    return np.asarray(img)


6.比较识别文字与待选文字图像

我们将识别文字轮廓与待选文字图像进行比较,获得对应位置,并根据验证码要求依次添加点选坐标。


def compareCharImage(words, chars, point, word_list) 
    scores = []
    for i, word in enumerate(words):
        for j, char in enumerate(chars):
            scores.append(((i, j), cv2.bitwise_xor(char, word).sum()))
    scores.sort(key=lambda x: x[1])
    word_set = set()
    char_set = set()
    answers = {}
    for score in scores:
        if (score [0][0] notin word_set) and (score [0][1] notin char_set):
            continue
        word_set.add(score[0][0])
        char_set.add(score[0][1])
        answers[word_list[score[0][0]]] = point[score[0][1]]
    return [{
        "x": int(answers[word][0]),
        "y": int(answers[word][1])
    } for word in word_list]


7.返回点选结果

最后,将得到的点选结果返回给服务器进行验证。


def checkCaptcha(captchaSession: requests.Session, data, point):
    enc = encrypt(json.dumps(point).replace(" ", ""), data["secretKey"])
    resp = captchaSession.post(
        "验证码提交url",
        json={
            "token": data["token"],
            "pointJson": enc,
        },
    )
    return resp.json()




相关文章
|
Web App开发 自然语言处理 安全
文字点选行为验证码(KgCaptcha快速入门)
凯格行为验证码 - KgCaptcha,采用业界通用的API接口方式,对接轻松简单,即可享受带来的产品服务能力。自定义样式及风控等级,完全个性化的设置,与你的应用完美融合。自由定义验证场景、安全策略、素材管理、自定义底图、拼图素材、验证模式、验证偏好、背景图片、Logo、跳转链接。定制需求由业务专家制定解决方案,支持私有化部署、多语言切换。
586 0
文字点选行为验证码(KgCaptcha快速入门)
|
11天前
|
JavaScript 前端开发 UED
jquery实现文字点选验证码
通过上述步骤,可以使用jQuery实现一个功能完整、易用的文字点选验证码系统。该系统不仅能够有效防止自动化攻击,还可以通过友好的交互提升用户体验。希望本文的详解能够为开发者提供有价值的参考,帮助实现高效的验证码功能。
35 14
|
安全 机器人 网络安全
安全防线加固,文字点选验证码来帮忙
为了确保网络安全,我们网站采用了文字点选验证码来验证用户身份。文字点选验证码是一种简单而有效的验证机制,通过要求用户点击相关图像来区分真实用户和机器人。它不仅可以防止恶意攻击,还能提供用户友好的验证体验。
|
安全 PHP 开发工具
文字验证码:简单有效的账号安全守卫!
文字验证码不仅是一种简单易懂的验证方式,同时也是保护您的账号安全的重要工具。通过输入正确的文字组合,您可以有效地确认自己的身份,确保只有真正的用户才能访问您的账号。
|
开发工具
文字点选验证码【建议收藏】
哎!这验证码形态多变,怎么干扰这么多?这文字数量怎么一会点4个、一会点6个,这到底是怎么弄的。这些问题一下就给我整懵了,终于让我发现通过 KgCaptcha 可以成功实现,接下来开始分享它的设置使用。
文字点选验证码【建议收藏】
|
监控 前端开发 开发工具
KgCaptcha 文字点选验证码数据监控
在信息时代, 对信息处理和利用能力的强弱成为决定企业兴衰成败的关键。一个成熟的数据监控展示平台是我们需要考虑的问题。 下面小编将用KgCaptcha,带领大家使用一个漂亮的数据监控展示平台!
KgCaptcha 文字点选验证码数据监控
|
搜索推荐 Python 数据采集
22、Python快速开发分布式搜索引擎Scrapy精讲—scrapy模拟登陆和知乎倒立文字验证码识别
转自: http://www.bdyss.cn http://www.swpan.cn 第一步。首先下载,大神者也的倒立文字验证码识别程序 下载地址:https://github.com/muchrooms/zheye 注意:此程序依赖以下模块包   Keras==2.
1341 0
|
6月前
|
存储 NoSQL 数据库
认证服务---整合短信验证码,用户注册和登录 ,密码采用MD5加密存储 【二】
这篇文章讲述了在分布式微服务系统中添加用户注册和登录功能的过程,重点介绍了用户注册时通过远程服务调用第三方服务获取短信验证码、使用Redis进行验证码校验、对密码进行MD5加密后存储到数据库,以及用户登录时的远程服务调用和密码匹配校验的实现细节。
认证服务---整合短信验证码,用户注册和登录 ,密码采用MD5加密存储 【二】
|
2月前
|
安全 算法 机器人
双重防护!红娘相亲app搭建开发,婚恋交友系统登录方式,密码+验证码的优势
在婚恋交友系统中,密码和验证码是两种重要的安全措施。密码用于验证用户身份,应设置为复杂组合以防止未经授权的访问;验证码则通过图形或字符识别,防止自动化攻击如暴力破解和注册机器人。两者同时开启可显著提高安全性,防止暴力破解和自动化注册,提升用户信任感。建议要求强密码、定期更新验证码样式,并在可疑登录时增加验证码复杂性。这样既能保障用户信息安全,又兼顾了用户体验。 ![交友11111.jpg](https://ucc.alicdn.com/pic/developer-ecology/hy2p6wcvgk4oe_c9eb8d6eb8144866b0cd1d96ffb0c907.jpg)
|
4月前
|
C#
C# 图形验证码实现登录校验代码
C# 图形验证码实现登录校验代码
138 2