python web框架Flask实现图形验证码及验证码的动态刷新实例

作者:呱唧_T_呱唧 时间:2021-01-09 15:35:53 

下列代码都是以自己的项目实例讲述的,相关的文本内容很少,主要说明全在代码注释中

自制图形验证码

这里所说的图形验证码都是自制的图形,通过画布、画笔、画笔字体的颜色绘制而成的。将验证码封装成一个类比较好管理,代码里有绝对详细的注释,当然大家可以直接复制。

里面涉及的字体都是从系统电脑上自带的,大家直接复制当前目录下就可以了。


主目录/utils/captcha/__init__.py

import random
import string

# Image:一个画布
# ImageDraw:一个画笔
# ImageFont:画笔的字体
from PIL import Image, ImageDraw, ImageFont

# Captcha验证码
class Captcha(object):
 # 生成4位数的验证码
 numbers = 4
 # 验证码图片的宽度和高度
 size = (100, 30)
 # 验证码字体大小
 fontsize = 25
 # 加入干扰线的条数
 line_number = 2

# 构建一个验证码源文本
 SOURCE = list(string.ascii_letters)
 for index in range(0, 10):
   SOURCE.append(str(index))

# 用来绘制干扰线
 @classmethod
 def __gene_line(cls, 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=cls.__gene_random_color(), width=2)

# 用来绘制干扰点
 @classmethod
 def __gene_points(cls, draw, point_chance, width, height):
   # 大小限在【0, 100】中
   chance = min(100, max(0, int(point_chance)))
   for w in range(width):
     for h in range(height):
       tmp = random.randint(0, 100)
       if tmp > 100 - chance:
         draw.point((w, h), fill=cls.__gene_random_color())

# 生成随机颜色
 @classmethod
 def __gene_random_color(cls, start=0, end=255):
   random.seed()
   return (random.randint(start, end),
       random.randint(start, end),
       random.randint(start, end))

# 随机选择一个字体
 @classmethod
 def __gene_random_font(cls):
   fonts = [
     "PAPYRUS.TTF",
     "CENTAUR.TTF",
     "Inkfree.ttf",
     "verdana.ttf",
   ]
   font = random.choice(fonts)
   return "utils/captcha/"+font

# 用来随机生成一个字符串(包括英文和数字)
 @classmethod
 def gene_text(cls, numbers):
   # numbers是生成验证码的位数
   return " ".join(random.sample(cls.SOURCE, numbers))

# 生成验证码
 @classmethod
 def gene_graph_captcha(cls):
   # 验证码图片的宽高
   width, height = cls.size
   # 创建图片
   image = Image.new("RGBA", (width, height), cls.__gene_random_color(0, 100))
   # 验证码的字体
   font = ImageFont.truetype(cls.__gene_random_font(), cls.fontsize)
   # 创建画笔
   draw = ImageDraw.Draw(image)
   # 生成字符串
   text = cls.gene_text(cls.numbers)
   # 获取字体的尺寸
   font_width, font_height = font.getsize(text)
   # 填充字符串
   draw.text(((width-font_width)/2, (height-font_height)/2),
        text, font=font, fill=cls.__gene_random_color(150, 255))
   # 绘制干扰线
   for x in range(0, cls.line_number):
     cls.__gene_line(draw, width, height)
   # 绘制干扰点
   cls.__gene_points(draw, 10, width, height)
   with open("captcha.png", "wb") as fp:
     image.save(fp)
   return text, image

显示图形验证码

一般图形验证码都是在表单中,这样短时间内的数据及建议保存在redis缓存中(用户点击动态刷新图形验证码)。首先我们绘制图形验证码保存到项目的目录下(入口文件是主目录(项目目录)app.py文件,图片也保存到主目录下),然后通过url地址访问自制的图形验证码(这里我只添加主要的代码)


主目录/common/views.py

@bp.route("/captcha")
def graph_captcha():
 """
 使用定义好的图形验证码类,来制作验证码
 以验证码为键、验证码为值(为了用户的体验,让其忽略大小写)存储在redis缓存中
 通过BytesIO字节流的方式保存和访问图片
 :return: 图片响应
 """
 # 获取验证码
 text, image = Captcha.gene_graph_captcha()
 cpcache.set(text.lower(), text.lower())

# BytesIO:字节流
 out = BytesIO()
 # 保存图片
 image.save(out, "png")
 # 存储完图片,将文件的指针指向文件头,使下次保存图片能覆盖前面保存的图片,节省空间
 out.seek(0)
 # 访问图片,并将其作为一个响应返回给前台
 resp = make_response(out.read())
 resp.content_type = "image/png"
 return resp

前端页面的代码如下:


<div class="form-group">
 <div class="input-group">
   <input type="text" class="form-control" name="graph_captcha" placeholder="图形验证码">
   <span class="input-group-addon captcha-addon">
     <img id="captcha-img" class="captcha-img" src="{{ url_for("common.graph_captcha") }}" alt="">
   </span>
 </div>
</div>

动态刷新验证码

无非就是再生成一张图形验证码,通过url再次访问就可以,但是这样做是非常麻烦的,这里我很难解释(很难!!!),大家就直接复制代码吧,这个代码就是点击图片生成一个新的url访问图片


这个文件放在公共的目录下就可以了

var cpparam = {
 setParam: function(href, key, value){
   //重新加载整个页面
   var isReplaced = false;
   var urlArray = href.split("?");
   if(urlArray.length > 1){
     var queryArray = urlArray[1].split("&");
     for(var i=0; i < queryArray.length; i++){
       var paramArray = queryArray[i].split("=");
       if(paramArray[0] == key){
         paramArray[1] = value;
         queryArray[i] = paramArray.join("=");
         isReplaced = true;
         break;
       }
     }
     if(!isReplaced){
       var params = {};
       params[key] = value;
       if(urlArray.length > 1){
         href = href + "$" + $.param(params);
       }else{
         href = href + "?" + $.param(params);
       }
     }else{
       var params = queryArray.join("&");
       urlArray[1] = params;
       href = urlArray.join("?");
     }
   }else{
     var param = {};
     param[key] = value;
     if(urlArray.length > 1){
       href = href + "$" + $.param(param);
     }else{
       href = href + "?" + $.param(param);
     }
   }
   return href;
 }
};

对应html的js文件就需要实现元素(图片)点击刷新图片,调用上面的变量cpparam生成一章图片并访问。


$(function(){
 $("#captcha-img").on("click", function(){
   var self = $(this);
   var src = self.attr("src");
   var newsrc = cpparam.setParam(src, "xx", Math.random());
   self.attr("src", newsrc);
 });
});

来源:https://www.cnblogs.com/aitiknowledge/p/11669098.html

标签:python,web框架,Flask,验证码
0
投稿

猜你喜欢

  • 面向对象的XHTML与CSS编程

    2008-01-11 13:37:00
  • 教你制作1px边框表格的四种方法

    2008-10-04 10:16:00
  • python实现扫雷小游戏

    2023-02-15 11:58:58
  • Selenium执行完毕未关闭chromedriver/geckodriver进程的解决办法(java版+python版)

    2023-03-28 12:39:51
  • ASP 读取MP3文件帧的信息比特率,采样频率,播放时间

    2010-06-04 12:22:00
  • 用Assets 面板为你的站点定做颜色

    2007-02-03 11:39:00
  • ASP中模拟PHP的关联数组

    2009-12-25 16:31:00
  • django 基于中间件实现限制ip频繁访问过程详解

    2022-06-24 08:38:43
  • 如何在Python中将字符串转换为集合

    2023-08-26 07:31:11
  • Jsp+Servlet实现简单登录注册查询

    2023-07-15 18:08:08
  • 关于Python3 lambda函数的深入浅出

    2023-01-12 09:12:41
  • 微信小程序简单的canvas裁剪图片功能详解

    2023-08-24 07:49:20
  • php函数重载的替代方法--伪重载详解

    2023-11-18 10:24:06
  • 阿里系的中国雅虎新首页浅谈

    2008-07-16 12:19:00
  • python用字节处理文件实例讲解

    2023-07-18 12:44:50
  • asp中判断服务器是否安装了某种组件的函数

    2011-02-16 10:53:00
  • 较完善的日历组件js源码(兼容)

    2010-08-08 08:43:00
  • mysql5在rhel5下乱码问题及解决方法

    2010-12-03 16:26:00
  • 在select语句中使用top的一些小技巧

    2009-03-12 12:21:00
  • WEB2.0网页制作标准教程(11)不用表格的菜单

    2008-02-19 19:36:00
  • asp之家 网络编程 m.aspxhome.com