基本上,大家使用每一种网络服务都会遇到验证码,一般是网站为了防止容易注册,发帖而设置的验证手段。其生成原理是将一串随机产生的数字或者符号生成一幅图片,图片里加上一些干扰素)防止OCR。下面详细讲解如何生成验证码。
通常,除了配置好的Python环境以外,还需要有PIL库,PIL库的作用请参考之前的博客。
如果要生成验证码图片,首先要生成一个随机字符串,包含二十六个字母的大小写以及十个数字。
然后要创建一个图片,写入字符串,还需要注意这里面的字体是不同系统而定的,如果没有找到系统字体路径,也可以不设置,接下来要在图片上画几条干扰线。
最后创建扭曲,加上滤镜,用来增强验证码的效果。
以下是生成验证码图片的完整代码以及运行效果:
# coding = utf-8
import random, string, sys, math
from PIL import Image, ImageDraw, ImageFont, ImageFilter
font_path = 'C:\Windows\Fonts\simfang.ttf' # 字体的位置
number = 4 # 生成几位数的验证码
size = (80, 30) # 生成验证码图片的高度和宽度
bgcolor = (255, 255, 255) # 背景颜色 默认为白色
fontcolor = (0, 0, 255) # 字体颜色 默认蓝色
linecolor = (255, 0, 0) # 干扰线颜色,默认为红色
draw_line = True # 是否要加入干扰线
line_number = (1, 5) # 加入干扰线条数的上下限
# 用来生成一个字符串
def gene_text():
# source = list(string.letters)
"""
source = ['a', 'b', 'c', 'd', 'e',
'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z']
"""
source = list(string.ascii_letters)
for index in range(0, 10):
source.append(str(index))
return ''.join(random.sample(source, number)) # number 是生成验证码的位数
# 用来绘制干扰线
def gene_line(draw, width, height):
begin = (random.randint(0, width), random.randint(0, height))
end = (random.randint(0, width), random.randint(0, height))
draw.line([begin, end], fill=linecolor)
# 生成验证码
def gene_code():
width, height = size # 宽和高
image = Image.new('RGBA', (width, height), bgcolor) # 创建图片
font = ImageFont.truetype(font_path, 25) # 验证码的字体
draw = ImageDraw.Draw(image) # 创建画笔
text = gene_text() # 生成字符串
font_width, font_height = font.getsize(text)
draw.text(((width - font_width) / number, (height - font_height) / number), text
, font=font, fill=fontcolor) # 填充字符串
if draw_line:
gene_line(draw, width, height)
image = image.transform((width+20, height+10), Image.AFFINE,
(1, -0.3, 0, -0.1, 1, 0), Image.BILINEAR) # 创建扭曲
image = image.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜 边界加强
image.save('indecode.png')
if __name__ == "__main__":
gene_code()