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

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

基本思路


  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、跳转链接。定制需求由业务专家制定解决方案,支持私有化部署、多语言切换。
552 0
文字点选行为验证码(KgCaptcha快速入门)
|
数据采集 前端开发 开发者
滑动拼图验证码的原理和破解方法~
滑动拼图验证码的原理和破解方法~
2571 0
滑动拼图验证码的原理和破解方法~
|
安全 开发工具 Python
滑动拼图验证,摆脱烦人的验证码输入
你最近是否遇到过令人头疼的验证码?为何不让滑动拼图成为你的新选择呢?通过完成一个有趣的滑动拼图来验证你的身份,既能锻炼大脑,又能保护你的隐私。
滑动拼图验证,摆脱烦人的验证码输入
|
安全 机器人 网络安全
安全防线加固,文字点选验证码来帮忙
为了确保网络安全,我们网站采用了文字点选验证码来验证用户身份。文字点选验证码是一种简单而有效的验证机制,通过要求用户点击相关图像来区分真实用户和机器人。它不仅可以防止恶意攻击,还能提供用户友好的验证体验。
|
安全 开发工具 UED
告别验证码烦恼,轻松完成文字点选验证
文字点选验证码,作为一种创新的验证方式,正在逐渐取代传统的输入文字或数字的验证方式,为用户带来了更简单、直观的验证体验。它通过点击包含特定文字或物体的图片来完成验证,摆脱了繁琐的输入过程,让用户告别验证码的烦恼。
|
JavaScript API 数据安全/隐私保护
数美滑块验证码分析
本文以官网的滑块验证码为例,分析验证过程,完成模拟验证。
1420 0
数美滑块验证码分析
|
开发工具
文字点选验证码【建议收藏】
哎!这验证码形态多变,怎么干扰这么多?这文字数量怎么一会点4个、一会点6个,这到底是怎么弄的。这些问题一下就给我整懵了,终于让我发现通过 KgCaptcha 可以成功实现,接下来开始分享它的设置使用。
文字点选验证码【建议收藏】
|
监控 前端开发 开发工具
KgCaptcha 文字点选验证码数据监控
在信息时代, 对信息处理和利用能力的强弱成为决定企业兴衰成败的关键。一个成熟的数据监控展示平台是我们需要考虑的问题。 下面小编将用KgCaptcha,带领大家使用一个漂亮的数据监控展示平台!
KgCaptcha 文字点选验证码数据监控
|
开发工具 UED
行为验证码小图标修改
最近行为验证码在很多网站逐步流行起来,对用户体验来说,比较新颖,操作简单。下面我以滑动拼图验证码和文字点选验证码为例,通过 KgCaptcha 来说说如何修改验证码中的图标。
行为验证码小图标修改
|
开发工具
KgCaptcha 图形验证码图片样式设置
在一次项目开发中,需要对滑动拼图验证码的宽高、拼图缺口、滑块等样式进行自定义设置,于是我找啊找,终于让我找到了 KgCaptcha,用户可以自己设置验证码尺寸、外框、缺口样式、滑块等。下面就由我来介绍一下如何设置吧!
KgCaptcha 图形验证码图片样式设置