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实现带验证码网站的自动登陆实现代码
Jan 12 Python
Python实现将罗马数字转换成普通阿拉伯数字的方法
Apr 19 Python
Django自定义认证方式用法示例
Jun 23 Python
对python中的xlsxwriter库简单分析
May 04 Python
TensorFlow Session会话控制&amp;Variable变量详解
Jul 30 Python
使用python对excle和json互相转换的示例
Oct 23 Python
Python Numpy库datetime类型的处理详解
Jul 13 Python
python中如何使用insert函数
Jan 09 Python
python如何实现复制目录到指定目录
Feb 13 Python
python 实现在shell窗口中编写print不向屏幕输出
Feb 19 Python
Python爬虫抓取指定网页图片代码实例
Jul 24 Python
pytorch 权重weight 与 梯度grad 可视化操作
Jun 05 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中trim()函数简单使用指南
2015/04/16 PHP
PHP常见漏洞攻击分析
2016/02/21 PHP
PHP实现用户异地登录提醒功能的方法【基于thinkPHP框架】
2018/03/15 PHP
解决IE下select标签innerHTML插入option的BUG(兼容IE,FF,Opera,Chrome,Safari)
2010/05/13 Javascript
为JavaScript提供睡眠功能(sleep) 自编译JS引擎
2010/08/16 Javascript
基于jquery的滚动条滚动固定div(附演示下载)
2012/10/29 Javascript
jquery 实现二级/三级/多级联动菜单的思路及代码
2013/04/08 Javascript
JavaScript 获取任一float型小数点后两位的小数
2014/06/30 Javascript
jQuery实现tab选项卡效果的方法
2015/07/08 Javascript
js实现的鼠标滚轮滚动切换页面效果(类似360默认页面滚动切换效果)
2016/01/27 Javascript
微信小程序 ES6Promise.all批量上传文件实现代码
2017/04/14 Javascript
AngularJS动态菜单操作指令
2017/04/25 Javascript
JS笛卡尔积算法与多重数组笛卡尔积实现方法示例
2017/12/01 Javascript
Vue异步组件处理路由组件加载状态的解决方案
2018/09/07 Javascript
防止Layui form表单重复提交的实现方法
2019/09/10 Javascript
vue实现移动端拖动排序
2020/08/21 Javascript
[11:12]2018DOTA2国际邀请赛寻真——绿色长城OpTic
2018/08/10 DOTA
Python递归实现汉诺塔算法示例
2018/03/19 Python
Tensorflow 合并通道及加载子模型的方法
2018/07/26 Python
Django 登陆验证码和中间件的实现
2018/08/17 Python
解决pycharm py文件运行后停止按钮变成了灰色的问题
2018/11/29 Python
对Python 两大环境管理神器 pyenv 和 virtualenv详解
2018/12/31 Python
Python面向对象程序设计多继承和多态用法示例
2019/04/08 Python
详解python中__name__的意义以及作用
2019/08/07 Python
Python面向对象程序设计之继承、多态原理与用法详解
2020/03/23 Python
Python 排序最长英文单词链(列表中前一个单词末字母是下一个单词的首字母)
2020/12/14 Python
美国大尺码女装零售商:TORRID
2016/10/01 全球购物
linux面试题参考答案(8)
2016/04/19 面试题
大学毕业通用个人的求职信
2013/12/08 职场文书
金融专业毕业生自荐信
2014/06/26 职场文书
房屋过户委托书范本
2014/10/07 职场文书
2015年医德医风工作总结
2015/04/02 职场文书
2015年车间安全管理工作总结
2015/05/13 职场文书
jquery插件实现代码雨特效
2021/04/24 jQuery
Java输出Hello World完美过程解析
2021/06/13 Java/Android
Echarts如何重新渲染实例详解
2022/05/30 Javascript