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


Posted in Python onOctober 14, 2019

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

自制图形验证码

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

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

主目录/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);
  });
});

以上就是本次介绍的关于python web框架Flask实现图形验证码全部知识点内容,感谢大家的学习和对三水点靠木的支持。

Python 相关文章推荐
Python输出9*9乘法表的方法
May 25 Python
python使用matplotlib绘图时图例显示问题的解决
Apr 27 Python
python绘制双柱形图代码实例
Dec 14 Python
Python实现KNN邻近算法
Jan 28 Python
python pandas 如何替换某列的一个值
Jun 09 Python
python实现定时压缩指定文件夹发送邮件
Dec 22 Python
Python PyQt5 Pycharm 环境搭建及配置详解(图文教程)
Jul 16 Python
python自动化unittest yaml使用过程解析
Feb 03 Python
基于matplotlib xticks用法详解
Apr 16 Python
python中使用input()函数获取用户输入值方式
May 03 Python
记一次Django响应超慢的解决过程
Sep 17 Python
python将下载到本地m3u8视频合成MP4的代码详解
Nov 24 Python
执行Django数据迁移时报 1091错误及解决方法
Oct 14 #Python
解析Python3中的Import
Oct 13 #Python
Python英文文章词频统计(14份剑桥真题词频统计)
Oct 13 #Python
Python 转换RGB颜色值的示例代码
Oct 13 #Python
Django中自定义查询对象的具体使用
Oct 13 #Python
PyCharm导入python项目并配置虚拟环境的教程详解
Oct 13 #Python
Python 用三行代码提取PDF表格数据
Oct 13 #Python
You might like
PHP生成json和xml类型接口数据格式
2015/05/17 PHP
php实现将上传word文件转为html的方法
2015/06/03 PHP
php验证码的制作思路和实现方法
2015/11/12 PHP
Laravel 微信小程序后端实现用户登录的示例代码
2019/11/26 PHP
jquery淡化版banner异步图片文字效果切换图片特效
2014/04/08 Javascript
JavaScript字符串对象toLowerCase方法入门实例(用于把字母转换为小写)
2014/10/17 Javascript
JavaScript Math.ceil 方法(对数值向上取整)
2015/01/09 Javascript
JavaScript DOM基础
2015/04/13 Javascript
js实现一个链接打开两个链接地址的方法
2015/05/12 Javascript
JavaScript取得键盘按下方向键是哪个的方法
2015/08/04 Javascript
Angular ng-class详解及实例代码
2016/09/19 Javascript
D3.js实现拓扑图的示例代码
2018/06/30 Javascript
详解js中Array的方法及技巧
2018/09/12 Javascript
react中使用css的7中方式(最全总结)
2019/02/11 Javascript
layui监听下拉选框选中值变化的方法(包含监听普通下拉选框)
2019/09/24 Javascript
Vue——前端生成二维码的示例
2020/12/19 Vue.js
[03:42]2018完美盛典-《加冕》
2018/12/16 DOTA
在Python中处理XML的教程
2015/04/29 Python
Python使用multiprocessing创建进程的方法
2015/06/04 Python
Python自动化运维之IP地址处理模块详解
2017/12/10 Python
Python pymongo模块用法示例
2018/03/31 Python
python使用Turtle库绘制动态钟表
2018/11/19 Python
python实现求特征选择的信息增益
2018/12/18 Python
Python中的元组介绍
2019/01/28 Python
解决numpy矩阵相减出现的负值自动转正值的问题
2020/06/03 Python
Keras自定义IOU方式
2020/06/10 Python
Tory Burch美国官方网站:美国时尚生活品牌
2016/08/01 全球购物
爱尔兰灯和灯具网上商店:Lights.ie
2018/03/26 全球购物
茶叶店创业计划书范文
2014/01/19 职场文书
家长会学生演讲稿
2014/04/26 职场文书
希特勒的演讲稿
2014/05/23 职场文书
安全宣传标语
2014/06/10 职场文书
2015元旦晚会主持词(开场白+结束语)
2014/12/14 职场文书
环保建议书作文500字
2015/09/14 职场文书
python实现会员信息管理系统(List)
2022/03/18 Python
python区块链实现简版工作量证明
2022/05/25 Python