用python实现一个简单的验证码

 更新时间:2020年12月09日 11:42:06   作者:极客运维圈  
这篇文章主要介绍了用python实现一个简单的验证码的方法,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下

我们经常在登录一个网站,或者注册的时候需要输入一个验证码,有时候觉得很烦,因为有些验证码不仅复杂还看不清,许多用户就会因为这些而懒得再登录或者注册之类的。
既然验证码会造成流失用户的风险,为什么大家都还要使用验证码呢?
这是验证码在一定程度上起到保护网站安全的作用,比如防止大规模恶意注册(比如手机验证码形式,一机一户),再比如反爬虫(至少不会轻易让你爬取数据)等,你看用户基数最大的12306,就会有各种验证码。
既然验证码这么重要,它的原理是什么?是怎么实现的?
它的原理其实很简单,就是在服务器端生成验证码,发送给客户端,并以图像格式显示。客户端提交所显示的验证码,服务端接收并进行比较,若比对失败则不能实现登录或注册,反之成功后跳转相应界面。

我们知道了其原理,实现起来就很简单了,现在网络上也有各种各样已经做好的验证码,我们完全可以拿来即用。但是为了更好的理解其原理,我们来手撸一个简单的验证码,以下是在Django中实现。

简单的验证码

(1)、我们在urls.py中定义一条路由,如下:

url(r'getcode', views.get_code, name="get_code"),

(2)、我们定义一个视图函数get_code(),如下:

from io import BytesIO

from PIL import Image, ImageDraw, ImageFont
from django.conf import settings
from django.shortcuts import render, HttpResponse, redirect
def get_code(request):
  """
  手撸一个验证码
  """
  # 定义图像颜色模型
  mode = "RGB"
  # 定义图像尺寸
  size = (200, 100)
  # 定义背景色
  bg_color = (255, 0, 0)
  # 创建图像
  image = Image.new(mode=mode, size=size, color=bg_color)
  # 创建画布
  image_draw = ImageDraw.Draw(image, mode=mode)
  # 创建字体,第一个参数是字体,第二个参数是字体大小
  image_font = ImageFont.truetype(settings.FONT_PATH, 100)
  # 创建一个验证码
  verify_code = "Joke"
  # 生成验证码
  fill_color = (255,255,255)
  for i in range(4):
    image_draw.text(xy=(50 * i, 0), text=verify_code[i], font=image_font, fill=fill_color)
  # 保存图像
  fp = BytesIO()
  image.save(fp, "png")
  return HttpResponse(fp.getvalue(), content_type="image/png")

其中settings.FONT_PATH是我预先定义好的字段,如下

STATICFILES_DIRS = [  os.path.join(BASE_DIR, "statics"),]
FONT_PATH = os.path.join(os.path.join(STATICFILES_DIRS[0], "fonts"),"constan.ttf")

然后我们我们启动服务python manager.py runserver,在浏览器上就可以看到验证码生成了

能是实现了,但是我们现在是自定义了一个验证码字段,我们是需要随机生成验证码,而且字体颜色,背景颜色这些也不要定死了,然后我们再生成一些干扰点,我们对代码进行如下重构:

def get_code(request):
  """
  手撸一个验证码
  """
  # 定义图像颜色模型
  mode = "RGB"
  # 定义图像尺寸
  size = (200, 100)
  # 定义背景色
  bg_color = (get_color(), get_color(), get_color())
  # 创建图像
  image = Image.new(mode=mode, size=size, color=bg_color)
  # 创建画布
  image_draw = ImageDraw.Draw(image, mode=mode)
  # 创建字体,第一个参数是字体,第二个参数是字体大小
  image_font = ImageFont.truetype(settings.FONT_PATH, 100)
  # 创建一个验证码
  # verify_code = "Joke"
  verify_code = get_verify_code()
  # 生成验证码
  # fill_color = (255,255,255)
  for i in range(4):
    fill_color = (get_color(),get_color(),get_color())
    image_draw.text(xy=(50 * i, 0), text=verify_code[i], font=image_font, fill=fill_color)
  # 加入干扰点
  for i in range(10000):
    fill_color = (get_color(),get_color(),get_color())
    xy = (random.randrange(200), random.randrange(100))
    image_draw.point(xy=xy,fill=fill_color)
  # 保存图像
  fp = BytesIO()
  image.save(fp, "png")
  return HttpResponse(fp.getvalue(), content_type="image/png")


def get_color():
  """随机获取颜色"""
  return random.randrange(256)


def get_verify_code():
  """随机获取验证码"""
  verify_code = ''.join(random.choice(string.ascii_uppercase + string.digits + string.ascii_lowercase) for x in range(4))
  return verify_code

然后我们重启应用,刷新页面如下

是不是有点神似了?下面我们创建一个简单的login页面,来实际应用一下验证码。

简单的登录页面

(1)、创建一个路由

url(r'login',views.login, name="login"),

(2)、创建一个Login的视图函数

def login(request):
  """登录页面"""
  if request.method == "POST":
    pass
  return render(request, "login.html")

(3)、创建一个login.html的template

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Login</title>
</head>
<body>
<form action="{% url 'app01:login' %}" method="post">
	{% csrf_token %}
  <span>用户名:</span><input type="text" name="username">
  <br>
  <span>验证码:</span><input type="text" name="verify_code">
  <br>
  <img src="{% url 'app01:get_code' %}" alt="">
  <br>
  <button>登录</button>
</form>

</body>
</html>

然后重启服务,浏览器访问如下

现在我们只是简单的搭建起了流程,我们需要的功能还没有实现,我们需要的功能有:
1、验证码校验
2、点击图片自动刷新验证码
3、忽略大小写

我们现在对项目进行重构,如下:
(1)、我们在get_code视图函数添加一行代码,如下

# 创建一个验证码
  # verify_code = "Joke"
  verify_code = get_verify_code()
# 加入session
  request.session['verify_code'] = verify_code
  ......

(2)、修改login视图函数,如下

def login(request):
  """登录页面"""
  if request.method == "POST":
    storage_code = request.session.get("verify_code")
    submit_code = request.POST.get("verify_code")
    if storage_code.lower() == submit_code.lower():
      return HttpResponse("登录成功")
  return render(request, "login.html")

(3)、修改login.html代码如下

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Login</title>
</head>
<body>
<form action="{% url 'app01:login' %}" method="post">
  {% csrf_token %}
  <span>用户名:</span><input type="text" name="username">
  <br>
  <span>验证码:</span><input type="text" name="verify_code">
  <br>
  <img src="{% url 'app01:get_code' %}" alt="" name="verify_image">
  <br>
  <button>登录</button>
</form>
<script src="https://cdn.bootcss.com/jquery/3.2.0/jquery.js"></script>
<script>
  $(function () {
    $("img").on("click", function () {
      console.log("来了啊")
      $(this).attr("src","{% url 'app01:get_code' %}"+"?id="+Math.random())
    })
  })
</script>
</body>
</html>

然后就可以愉快的玩耍了,是不是很简单呢?

以上就是用python实现一个简单的验证码的详细内容,更多关于python 实现验证码的资料请关注脚本之家其它相关文章!

相关文章

  • python递归查询菜单并转换成json实例

    python递归查询菜单并转换成json实例

    本篇文章主要介绍了python递归查询菜单并转换成json实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-03-03
  • python中正则表达式与模式匹配

    python中正则表达式与模式匹配

    在之前找工作过程中,面试时经常被问到会不会python,懂不懂正则表达式。这篇文章主要介绍了python中正则表达式与模式匹配,需要的朋友可以参考下
    2019-05-05
  • Python帮你识破双11的套路

    Python帮你识破双11的套路

    一年一度的“双十一”又要来了,很多人已经开始摩拳擦掌,毕竟几天之后手还在不在就不好说了。看看Python帮你识破双11的套路,需要的朋友可以参考下
    2019-11-11
  • python实现字母闪烁效果的示例代码

    python实现字母闪烁效果的示例代码

    本文主要介绍了python实现字母闪烁效果的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • pycharm配置Anaconda虚拟环境全过程

    pycharm配置Anaconda虚拟环境全过程

    这篇文章主要介绍了pycharm配置Anaconda虚拟环境全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 原来我一直安装 Python 库的姿势都不对呀

    原来我一直安装 Python 库的姿势都不对呀

    平常我都是直接执行 pip install 安装的第三方库,很多教程也是这么介绍的,一直以来我都认为这是标准的、正确的安装 Python 第三方库的姿势。下面小编给大家分享一篇教程,一起看看吧
    2019-11-11
  • python3基于TCP实现CS架构文件传输

    python3基于TCP实现CS架构文件传输

    这篇文章主要为大家详细介绍了python3基于TCP实现CS架构文件传输,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • CentOS6.5设置Django开发环境

    CentOS6.5设置Django开发环境

    这篇文章主要为大家详细介绍了CentOS6.5设置Django开发环境,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • python实现websocket的客户端压力测试

    python实现websocket的客户端压力测试

    这篇文章主要为大家详细介绍了python实现websocket的客户端压力测试,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06
  • 在Python中,不用while和for循环遍历列表的实例

    在Python中,不用while和for循环遍历列表的实例

    今天小编就为大家分享一篇在Python中,不用while和for循环遍历列表的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-02-02

最新评论