Python中处理验证码有什么好的方法或思路?
验证码

验证码字符只有 英文加数字; 我的思路:转为灰度,二值化处理,除去干扰横线(正在做),然后用 pytesseract 识别。干扰线除去有点儿复杂 正在做还不知道识别率有多大...
干掉干扰线 你们有没有啥头绪? 干扰线纵向都是 3 个像素,我目前的想法就是:纵向检测 3 像素的黑线
这是简单处理后的 还没有解决干扰线

Python中处理验证码有什么好的方法或思路?
用 CNN
处理验证码通常分两种情况:自己生成和自动识别。
生成验证码:
用 Pillow 库画图,加上随机字符、干扰线、噪点就行。下面是个简单例子:
from PIL import Image, ImageDraw, ImageFont
import random
import string
def generate_captcha():
width, height = 180, 60
img = Image.new('RGB', (width, height), color='white')
draw = ImageDraw.Draw(img)
# 画干扰线
for _ in range(5):
x1 = random.randint(0, width)
y1 = random.randint(0, height)
x2 = random.randint(0, width)
y2 = random.randint(0, height)
draw.line([(x1, y1), (x2, y2)], fill='gray', width=2)
# 生成随机字符
chars = ''.join(random.choices(string.ascii_uppercase + string.digits, k=4))
font = ImageFont.truetype('arial.ttf', 36)
# 画文字(每个字符位置随机偏移一点)
x_offset = 10
for ch in chars:
y_offset = random.randint(-5, 5)
draw.text((x_offset, 10 + y_offset), ch, fill='black', font=font)
x_offset += 40
# 加噪点
for _ in range(200):
x = random.randint(0, width)
y = random.randint(0, height)
draw.point((x, y), fill='gray')
img.save('captcha.png')
return chars, img
# 使用
text, image = generate_captcha()
print(f'验证码文本:{text}')
自动识别验证码:
简单的可以用 pytesseract(OCR),但复杂验证码效果差。这时候要么用机器学习(CNN训练),要么直接找打码平台(第三方API)。
import pytesseract
from PIL import Image
def recognize_captcha(image_path):
img = Image.open(image_path)
# 预处理:转灰度、二值化等能提升识别率
img = img.convert('L')
text = pytesseract.image_to_string(img, config='--psm 8')
return text.strip()
复杂验证码就上 CNN 或者 EasyOCR 这类库,但需要自己标注数据训练。
总结:简单验证码自己生成和识别都不难,复杂的建议用现成API。
直接用 OCR 呢
安利一下简单粗暴的卷积神经网络脚本: https://github.com/nickliqian/cnn_captcha
这个是用谷歌开源的 kaptcha 生成的,可以使用机器学习进行训练
似乎不是,但方法是一样的
不用机器学习的话,看上去字比线粗,可以使用一个像素周围一定范围不是黑就去掉的办法,结果是线没了,字变细
这种样本量少的话真不好做,建议使用收费的打码平台 api。
pytesseract 暑假里面用的时候发现其对手写文本的识别率极差,这种倾斜变形的字体可能识别效果也不会很好。
如果没有图像处理的知识,建议还是打码吧! 简单粗暴效率超高!
图像处理里有一个操作叫 erosion,你可以试试看
一楼说的对,cnn 比较好。
这种类型的验证码用传统的图像算法和 tesseract 效果应该都不会好。会算法技术就试下训练网络,不行的话找打码平台吧
看了以后,我还是选择第三方的接口吧
只有数字和字母?? CNN100 张就够,在线训练的网址也有
打码平台挺便宜的,可以考虑一下,30 块可以打 1000 张。。。
不行的 老哥,项目上线了远不止 1000 张 而且只是个 个人项目,没有收入来源。
我了解一下
之前写爬虫用过 pytesseract,用各种常规方法处理验证码图片,最后效果反而不好,我最终的解决方案是不处理图片,直接识别,识别失败则重新请求验证码,再识别,无限循环。一般十几次之内能识别出来。
个人项目的话如果不是后台跑着帮用户 24 小时收集数据的项目的话,就直接把验证码扔给用户让用户填啊。
剩下打码平台用不起的话,那就只能自己学图像处理了。或者简单粗暴上 cnn
这有干扰线的 根本识别不出来。有干扰线的 肯定要解决干扰线
老哥 求个链接
pytesseract 不能识别这种会变形的文字,所以还是上 cnn 吧
好的点子就是悬赏。。。出个 500、800 的,问题就解决了。。。
腐蚀再膨胀说不定能去掉
有个问题,你能写出生成这种验证码的代码吗?可以的话,就可以用 CNN 开心的训练了
数据量足够的话,这种的 case 肯定能解决的
那我就爱莫能助了
你或许需要一些 hacker 思维,寻找干扰线与正常字符之间的差别规律,然后针对这个规律写处理代码。其实还挺有意思的,这是测试效果:
只要能做到有效分割,也就基本意味着破解成功了,分割之后大概只需要标注 100 张左右,这点体力活比起直接用 CNN 撸(需要标注上万张)还是很容易接受的,后面再随便在 sklearn 里挑一个算法来训练就行了。
对了,对于你这种验证码,如上图连在一起的,直接从中间分开就行了,不会差很多,对于单个字符,只要你人能认出来,多层感知器训练后认出来没问题。大不了就跳过,从新刷新一张。识别成功率能到 50%就能用了。
思路很棒,谢谢


