京公网安备 11010802034615号
经营许可证编号:京B2-20210330
作者:Kevin
来源:麦叔编程
最近感觉被大数据定义成机器人了,随便看个网页都跳验证码。
怎么用python绕验证码是个令人头秃的事情,
我投降!那么今天手把手教大家如何写验证码,去为难别人,让他们头秃。
说错了,其实就是教大家如何通过python代码去生成验证码~~
pip install pillow
# 导入相关的绘画模块 from PIL import Image, ImageDraw, ImageFont # 设置背景色 bg_color = (100, 100, 255) #设置画布长宽(像素) width = 400 height = 100 # 通过设置生成新的画布 im = Image.new('RGB',(width,height),bg_color) # 展示画布 im.show()
在这bg_color背景色的设置是用RGB颜色标准去设置的,如果你不喜欢这个背景色可以自己调一下。
“
常见的RGB颜色
运行代码后:
先上代码
from PIL import Image, ImageDraw, ImageFont # 省略第一步的代码 # 创建画笔对象 draw = ImageDraw.Draw(im) # 验证码文本 string = 'MSBC' # 构造字体对象 font = ImageFont.truetype('./ziti.ttf', 90) # font = ImageFont.load_default().font # 构造字体颜色 fontcolor = (255, 100, 100) # 绘制4个字 draw.text((10, 2), string[0], font=font, fill=fontcolor)
draw.text((110, 2), string[1], font=font, fill=fontcolor)
draw.text((210, 2), string[2], font=font, fill=fontcolor)
draw.text((310, 2), string[3], font=font, fill=fontcolor) #释放画笔 del draw #展示图片 im.show()
代码分析:
draw = ImageDraw.Draw(im)
在im画布上实例化一只笔。
font = ImageFont.truetype('./ziti.ttf', 90) # font = ImageFont.load_default().font
第一个参数是设置字体,我这有下载一个ttf的字体文件所以可以用它,如果没有指定的字体文件可以使用默认的# font = ImageFont.load_default().font;
第二个参数是绘制字体的大小,因为我们画布是400x100的 所以我们为了美观就把字体设成90x90的尺寸。
# 构造字体颜色 fontcolor = (255, 100, 100)
字体文本的颜色,参照第一步画布的RGB设置。
# 绘制4个字 draw.text((10, 2), string[0], font=font, fill=fontcolor)
draw.text((110, 2), string[1], font=font, fill=fontcolor)
draw.text((210, 2), string[2], font=font, fill=fontcolor)
draw.text((310, 2), string[3], font=font, fill=fontcolor)
这里draw.text函数,顾名思义就是开始拿画起画笔开始写字,
第一个参数 写字的坐标;
第二个参数 要写的字;
第三个参数 字的颜色(上面构造过了,你也可以设成一字一色)。
代码跑一下看成果:
效果还行,就是总觉得少了点什么?
既然是验证码,肯定要稍微难识别,上面那个那么傻白甜的验证码是怎么回事??
这一步我们需要导入random模块,因为干扰是不规则随机生成的。
import random from PIL import Image, ImageDraw, ImageFont # 省略第一步代码 # 省略第二步代码 #使用point函数绘制噪点 for i in range(0, 100): xy = (random.randrange(0, width), random.randrange(0, height)) fill = (random.randrange(0, 255), 255, random.randrange(0, 255)) draw.point(xy, fill=fill) #释放画笔 del draw im.show()
代码分析:
import random
别忘了导入random模块
for i in range(0, 100): xy = (random.randrange(0, width), random.randrange(0, height)) fill = (255, 255, 255) draw.point(xy, fill=fill)
一个循环100次的for循环,
xy变量是画干扰点的坐标值
fill变量是噪点的颜色,还是RGB标准的
draw.point 画点的动作
“
这个for循环的次数越多,画布上噪点也会相应增多。
跑一下代码看看噪点的效果如何:
感觉还是有点傻白甜,我们来循环1000次的试试:
10000次!
够了。
这一步我将各个参数结合random模块,使我们的验证码更难辨别!
import random from PIL import Image, ImageDraw, ImageFont
bg_color = (random.randrange(20, 120), random.randrange(20, 120), random.randrange(150, 255))
width = 400 height = 100 im = Image.new('RGB',(width,height),bg_color)
# 创建画笔对象
draw = ImageDraw.Draw(im)
# 构造字体对象
font = ImageFont.truetype('./ziti.ttf', 100)
# font = ImageFont.load_default().font
# 构造字体颜色
fontcolor = (random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255))
# 绘制4个字 string = 'MSBC' draw.text((random.randint(10, 30), (random.randint(0, 10))), string[0], font=font, fill=fontcolor)
draw.text((random.randint(90, 130), (random.randint(0, 10))), string[1], font=font, fill=fontcolor)
draw.text((random.randint(180, 230), (random.randint(0, 10))), string[2], font=font, fill=fontcolor)
draw.text((random.randint(270, 330), (random.randint(0, 10))), string[3], font=font, fill=fontcolor)
#调用画笔的point()函数绘制噪点 for i in range(0, 10000):
xy = (random.randrange(0, width), random.randrange(0, height))
fill = (random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255))
draw.point(xy, fill=fill)
#释放画笔
del draw
im.show()
我把字体颜色,噪点颜色,文本位置都结合了random模块,效果图如下:
这一步,我们需要把上面的代码封装到函数中,大致把上面代码重构成:
# 使用for循环生成文本字符 # 生成验证码图片的函数,参数就是上面生成的文本 # 调用生成验证码图片函数
重构后:
import random from PIL import Image, ImageDraw, ImageFont string = '' #随机选取4个值作为验证码
rand_str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' for i in range(0, 4): string += rand_str[random.randrange(0, len(rand_str))]
def gen_verify_img(text):
bg_color = (random.randrange(20, 120), random.randrange(20, 120), random.randrange(150, 255))
width = 400 height = 100 im = Image.new('RGB',(width,height),bg_color)
# 创建画笔对象
draw = ImageDraw.Draw(im)
# 构造字体对象
font = ImageFont.truetype('./ziti.ttf', 100)
# font = ImageFont.load_default().font
# 构造字体颜色
fontcolor = (random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255))
# 绘制4个字
draw.text((random.randint(10, 30), (random.randint(0, 10))), string[0], font=font, fill=fontcolor)
draw.text((random.randint(90, 130), (random.randint(0, 10))), string[1], font=font, fill=fontcolor)
draw.text((random.randint(180, 230), (random.randint(0, 10))), string[2], font=font, fill=fontcolor)
draw.text((random.randint(270, 330), (random.randint(0, 10))), string[3], font=font, fill=fontcolor)
#调用画笔的point()函数绘制噪点 for i in range(0, 10000):
xy = (random.randrange(0, width), random.randrange(0, height))
fill = (random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255))
draw.point(xy, fill=fill)
#释放画笔
del draw
im.show()
# 调用函数
gen_verify_img(string)
把原先代码中的string变量提到了函数外,把它变成函数需要传入的参数,
再用for循环,随机选出4个字符。
string = '' #随机选取4个值作为验证码 rand_str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' for i in range(0, 4): string += rand_str[random.randrange(0, len(rand_str))]
代码再跑一下:
上面的验证码是 DZNO还是DZN0?
在web开发的登录操作,和训练验证码识别的神经运算中,都需要大量的验证码图片。
所以需要把大量的验证码图片文件,我们将批量验证码保存到本地。
完整代码:
import random from PIL import Image, ImageDraw, ImageFont
def gen_verify_img(text):
bg_color = (random.randrange(20, 120), random.randrange(20, 120), random.randrange(150, 255))
width = 400 height = 100 im = Image.new('RGB',(width,height),bg_color)
# 创建画笔对象
draw = ImageDraw.Draw(im)
# 构造字体对象
font = ImageFont.truetype('./ziti.ttf', 100)
# font = ImageFont.load_default().font
# 构造字体颜色
fontcolor = (random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255))
# 绘制4个字
draw.text((random.randint(10, 30), (random.randint(0, 10))), string[0], font=font, fill=fontcolor)
draw.text((random.randint(90, 130), (random.randint(0, 10))), string[1], font=font, fill=fontcolor)
draw.text((random.randint(180, 230), (random.randint(0, 10))), string[2], font=font, fill=fontcolor)
draw.text((random.randint(270, 330), (random.randint(0, 10))), string[3], font=font, fill=fontcolor)
#调用画笔的point()函数绘制噪点 for i in range(0, 10000):
xy = (random.randrange(0, width), random.randrange(0, height))
fill = (random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255))
draw.point(xy, fill=fill)
#释放画笔
del draw
# im.show()
im.save(f'./{text}.png','png') for i in range(100): string = '' #随机选取4个值作为验证码
rand_str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' for i in range(0, 4): string += rand_str[random.randrange(0, len(rand_str))]
gen_verify_img(string) print(f'{string} 验证码生成成功!!')
最后再跑一下:
部分验证码展示:
“
作者注:
如果再将本文中的代码进行变形或改写,可能会得到更五花八门的验证码,怎么发挥就看屏幕钱你的了。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在数字化商业环境中,数据已成为企业优化运营、抢占市场、规避风险的核心资产。但商业数据分析绝非“堆砌数据、生成报表”的简单 ...
2026-01-20定量报告的核心价值是传递数据洞察,但密密麻麻的表格、复杂的计算公式、晦涩的数值罗列,往往让读者望而却步,导致核心信息被淹 ...
2026-01-20在CDA(Certified Data Analyst)数据分析师的工作场景中,“精准分类与回归预测”是高频核心需求——比如预测用户是否流失、判 ...
2026-01-20在建筑工程造价工作中,清单汇总分类是核心环节之一,尤其是针对楼梯、楼梯间这类包含多个分项工程(如混凝土浇筑、钢筋制作、扶 ...
2026-01-19数据清洗是数据分析的“前置必修课”,其核心目标是剔除无效信息、修正错误数据,让原始数据具备准确性、一致性与可用性。在实际 ...
2026-01-19在CDA(Certified Data Analyst)数据分析师的日常工作中,常面临“无标签高维数据难以归类、群体规律模糊”的痛点——比如海量 ...
2026-01-19在数据仓库与数据分析体系中,维度表与事实表是构建结构化数据模型的核心组件,二者如同“骨架”与“血肉”,协同支撑起各类业务 ...
2026-01-16在游戏行业“存量竞争”的当下,玩家留存率直接决定游戏的生命周期与商业价值。一款游戏即便拥有出色的画面与玩法,若无法精准识 ...
2026-01-16为配合CDA考试中心的 2025 版 CDA Level III 认证新大纲落地,CDA 网校正式推出新大纲更新后的第一套官方模拟题。该模拟题严格遵 ...
2026-01-16在数据驱动决策的时代,数据分析已成为企业运营、产品优化、业务增长的核心工具。但实际工作中,很多数据分析项目看似流程完整, ...
2026-01-15在CDA(Certified Data Analyst)数据分析师的日常工作中,“高维数据处理”是高频痛点——比如用户画像包含“浏览次数、停留时 ...
2026-01-15在教育测量与评价领域,百分制考试成绩的分布规律是评估教学效果、优化命题设计的核心依据,而正态分布则是其中最具代表性的分布 ...
2026-01-15在用户从“接触产品”到“完成核心目标”的全链路中,流失是必然存在的——电商用户可能“浏览商品却未下单”,APP新用户可能“ ...
2026-01-14在产品增长的核心指标体系中,次日留存率是当之无愧的“入门级关键指标”——它直接反映用户对产品的首次体验反馈,是判断产品是 ...
2026-01-14在CDA(Certified Data Analyst)数据分析师的业务实操中,“分类预测”是高频核心需求——比如“预测用户是否会购买商品”“判 ...
2026-01-14在数字化时代,用户的每一次操作——无论是电商平台的“浏览-加购-下单”、APP的“登录-点击-留存”,还是金融产品的“注册-实名 ...
2026-01-13在数据驱动决策的时代,“数据质量决定分析价值”已成为行业共识。数据库、日志系统、第三方平台等渠道采集的原始数据,往往存在 ...
2026-01-13在CDA(Certified Data Analyst)数据分析师的核心能力体系中,“通过数据建立模型、实现预测与归因”是进阶关键——比如“预测 ...
2026-01-13在企业数字化转型过程中,业务模型与数据模型是两大核心支撑体系:业务模型承载“业务应该如何运转”的逻辑,数据模型解决“数据 ...
2026-01-12当前手游市场进入存量竞争时代,“拉新难、留存更难”成为行业普遍痛点。对于手游产品而言,用户留存率不仅直接决定产品的生命周 ...
2026-01-12