Python案例怎么生成图片验证码?

wen python案例 9

Python案例实战:手把手教你用Pillow生成图片验证码(含完整代码+常见问题解析)

📖 目录导读

  1. 为什么需要图片验证码?
  2. 核心工具:Pillow库安装与基础用法
  3. 从零开始:生成简单字母数字验证码
  4. 进阶美化:添加干扰线、噪点、扭曲效果
  5. 实战案例:生成带颜色的随机验证码图片
  6. 常见问题问答(Q&A)
  7. SEO优化建议与搜索引擎排名要点

为什么需要图片验证码?

在互联网时代,图片验证码(CAPTCHA)是防止恶意爬虫、刷票、暴力破解等自动化攻击的常见手段,它通过生成带有扭曲、噪声的文本图像,要求用户手动输入,从而区分人类与机器,Python因其丰富的第三方库,成为实现验证码生成的首选语言。

Python案例怎么生成图片验证码?

经典场景:网站登录、注册表单、评论提交、API接口防刷等。


核心工具:Pillow库安装与基础用法

Python中生成图片验证码最成熟的库是 Pillow(PIL的分支)。
安装命令

pip install Pillow

基础功能

  • Image.new():创建空白画布
  • ImageDraw.Draw:在图片上绘制文字、线条
  • ImageFont.truetype:加载字体文件(支持TTF)
  • random模块:生成随机颜色、字符

从零开始:生成简单字母数字验证码

以下代码生成4位随机字母+数字组合的验证码图片:

from PIL import Image, ImageDraw, ImageFont
import random
import string
# 设置参数
width, height = 160, 60
font_path = "arial.ttf"  # 可替换为其他字体文件
font_size = 36
bg_color = (255, 255, 255)  # 白色背景
# 生成随机4位字符(字母+数字)
def random_text(length=4):
    return ''.join(random.choices(string.ascii_uppercase + string.digits, k=length))
# 创建画布
image = Image.new('RGB', (width, height), bg_color)
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(font_path, font_size)
# 绘制验证码文字(每个字符颜色随机)
text = random_text()
x_start = 10
for char in text:
    color = (random.randint(0, 200), random.randint(0, 200), random.randint(0, 200))
    draw.text((x_start, 10), char, fill=color, font=font)
    x_start += 35
image.save("simple_captcha.png")

输出效果:一张白底带4个彩色字符的图片,无干扰。


进阶美化:添加干扰线、噪点、扭曲效果

真实场景中,验证码必须增加干扰以提升破解难度:

from PIL import ImageFilter
# 添加干扰线(2条随机线条)
for _ in range(2):
    start = (random.randint(0, width), random.randint(0, height))
    end = (random.randint(0, width), random.randint(0, height))
    draw.line([start, end], fill=(0, 0, 0), width=2)
# 添加噪点(随机像素点)
for _ in range(100):
    x = random.randint(0, width-1)
    y = random.randint(0, height-1)
    image.putpixel((x, y), (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
# 应用模糊滤镜(增加扭曲感)
image = image.filter(ImageFilter.BLUR)
image.save("enhanced_captcha.png")

关键点:线条和噪点颜色应尽量与文字色接近但不同,避免被简单过滤。


实战案例:生成带颜色的随机验证码图片

一个完整的验证码生成函数(可直接集成到Web应用):

def generate_captcha(text_length=4, width=160, height=50, font_path="arial.ttf"):
    # 创建背景渐变(随机色)
    from random import randint
    bg_color_start = (randint(200, 255), randint(200, 255), randint(200, 255))
    bg_color_end = (randint(100, 200), randint(100, 200), randint(100, 200))
    image = Image.new('RGB', (width, height), bg_color_start)
    draw = ImageDraw.Draw(image)
    # 绘制垂直渐变背景(模拟)
    for y in range(height):
        ratio = y / height
        r = int(bg_color_start[0] * (1 - ratio) + bg_color_end[0] * ratio)
        g = int(bg_color_start[1] * (1 - ratio) + bg_color_end[1] * ratio)
        b = int(bg_color_start[2] * (1 - ratio) + bg_color_end[2] * ratio)
        draw.line([(0, y), (width, y)], fill=(r, g, b))
    # 绘制文字(字符随机位置微调)
    font = ImageFont.truetype(font_path, 28)
    text = random_text(text_length)
    x = 10
    for char in text:
        y_offset = randint(-5, 5)  # 上下偏移
        char_color = (randint(50, 180), randint(50, 180), randint(50, 180))
        draw.text((x, 10 + y_offset), char, fill=char_color, font=font)
        x += 35
    # 干扰椭圆
    for _ in range(3):
        draw.ellipse([randint(0, width), randint(0, height), 
                     randint(10, 60), randint(10, 60)], 
                     outline=(randint(0, 100), randint(0, 100), randint(0, 100)))
    # 保存为内存流(用于直接返回HTTP响应)
    from io import BytesIO
    buf = BytesIO()
    image.save(buf, format='PNG')
    buf.seek(0)
    return buf, text  # 返回图片字节流和真实验证码文本
# 使用示例
img_bytes, code_text = generate_captcha()
print(f"验证码文本: {code_text}")

应用集成:在Flask/Django中可直接返回img_bytes,并存储code_text到Session供验证。


常见问题问答(Q&A)

❓ Q1: 为什么生成的验证码字体显示为乱码或方块?

A: 通常是因为 字体路径错误系统缺少对应字体,建议使用绝对路径,如 C:/Windows/Fonts/arial.ttf(Windows)或 /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf(Linux),也可下载免费字体文件(如simhei.ttf)放在项目目录。

❓ Q2: 如何让验证码更难被OCR识别?

A: 综合使用以下技术:

  • 文字扭曲变形(可用Image.transform
  • 叠加多个透明层
  • 随机字符间距和旋转角度
  • 使用彩色斑点背景而非纯色
  • 加入字符之间的粘连(字符重叠)

❓ Q3: 生成验证码后的图片流如何直接返回给前端?

A: 使用BytesIO将图片保存到内存,再通过Web框架的send_fileResponse输出,例如Flask:

from flask import Flask, make_response
@app.route('/captcha')
def captcha():
    img_bytes, code = generate_captcha()
    response = make_response(img_bytes.getvalue())
    response.headers['Content-Type'] = 'image/png'
    return response

❓ Q4: 验证码文本需要区分大小写吗?

A: 通常忽略大小写,因为字母识别易混淆(如“0”与“O”),建议统一转大写存储,前端输入时自动转大写再比较。


SEO优化建议与搜索引擎排名要点

为了让本文在必应(Bing)谷歌(Google)获得良好排名,需遵循以下规则:
包含核心关键词中“Python案例”、“生成图片验证码”直接命中用户搜索意图。
2.
使用H2/H3标签本文目录导读采用Markdown的、,搜索引擎会视为主标题结构。
3.
自然嵌入长尾关键词如“Pillow库验证码”、“Python验证码生成函数”、“网页验证码实现”。
4.
提供可复现的代码块搜索引擎偏好“解决实际问题”的内容,本文每段代码均需可独立运行。
5.
常见问答模块问答形式直接匹配用户搜索的疑问句式(如“怎么生成”、“为什么不行”)。
6.
内链与外链**(注意域名已按您要求修改):

  • 内部链接:推荐相关文章如《Python图片处理大全》
  • 外部链接:引用Pillow官方文档(如 pillow.readthedocs.io
  1. 页面加载速度:本文代码块均用反引号包裹,避免大图片拖慢页面。

最终建议:在实际网站发布时,为每段代码添加<pre><code>标签,并增加文章摘要(meta description)如“本文详细讲解Python用Pillow生成图片验证码的完整案例,包含干扰线、扭曲、随机颜色等核心技巧,附Q&A解答常见错误。”


通过以上步骤,您已掌握Python生成图片验证码的完整技术栈,若需更复杂的动态验证码(如行为验证),可进一步研究captcha库或集成第三方服务。

抱歉,评论功能暂时关闭!