首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django实战-信息资讯-图形验证码

Django实战-信息资讯-图形验证码

作者头像
小团子
发布2019-07-18 16:36:28
5490
发布2019-07-18 16:36:28
举报
文章被收录于专栏:数据云团数据云团数据云团

Django网络应用开发的5项基础核心技术包括模型(Model)的设计,URL 的设计与配置,View(视图)的编写,Template(模板)的设计和Form(表单)的使用。

有些网站的注册和登录会用到图形验证码,但随着爬虫技术的进步,图形验证码从简单的字母和数字,到比较高要求的滑块和点击选择文字。

本次项目会用到 PIL 图像处理标准库来生成图形验证码。

pip install Pillow

图像缩放操作

from PIL import Image

# 打开一个jpg图像文件,注意路径要改成你自己的:
im = Image.open('/Users/app/data/test.jpg')
# 获得图像尺寸:
w, h = im.size
# 缩放到50%:
im.thumbnail((w//2, h//2))
# 把缩放后的图像用jpeg格式保存:
im.save('/Users/app/data/thumbnail.jpg', 'jpeg')

① 生成图形验证码

import random
import string
import time
import os
from PIL import Image, ImageDraw, ImageFont

Image 是一个画板(context) ImageDraw 是一个画笔 ImageFont 画笔的字体。

  • 把一些常量抽取成类属性

需要定义图形验证码中的字体,生成几位数的验证码,图形和字体的大小,图形的背景颜色和字体的颜色。

class Captcha(object):
    # 字体的位置
    font_path = os.path.join(os.path.dirname(__file__), "Verdana.ttf")
    # font_path = 'utils/captcha/verdana.ttf'
    # 生成几位数的验证码
    number = 4
    # 生成验证码图片的宽度和高度
    size = (100, 40)
    #背景颜色默认为白色 RGB(Red,Green,Blue)
    bgcolor = (0, 0, 0)
    #随机字体颜色
    random.seed(int(time.time()))
    fontcolor = (random.randint(200, 255), random.randint(100, 255), random.randint(100, 255))
    #验证码字体大小
    fontsize = 20
    #随机干扰线颜色
    linecolor = (random.randint(0, 250), random.randint(0, 255), random.randint(0, 250))
    #是否要加入干扰线
    draw_line = True
    #是否要绘制干扰点
    draw_point = True
    #加入干扰线的条数
    line_number = 3
    #用来随机生成一个字符串(包括英文和数字)
    SOURCE = list(string.ascii_letters)
    for index in range(0, 10):
        SOURCE.append(str(index))
  • 取样 number是生成验证码的位数

定义成类方法,然后是私有的,对象在外面不能直接调用。

@classmethod
def gene_text(cls):
    return ''.join(random.sample(cls.SOURCE, cls.number))
绘制干扰线
@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.linecolor)
  • 绘制干扰点
@classmethod
def __gene_point(cls, draw, point_chance, width, height):
    chance = min(100, max(0, int(point_chance))) # 大小限制在 [0 , 100]
    for w in range(width):
        for h in range(height):
            tmp = random.randint(0, 100)
            if tmp > 100 - chance:
                draw.point((w, h), fill=(0, 0, 0))
  • 生成验证码
@classmethod
def gene_code(cls):
    width, height = cls.size # 获取宽和高
    image = Image.new('RGBA', (width, height), cls.bgcolor) # 创建图片 RGB A是透明度
    font = ImageFont.truetype(cls.font_path, cls.fontsize)
    draw = ImageDraw.Draw(image) # 创建画笔
    text = cls.gene_text() # 生成字符串
    font_width, font_height = font.getsize(text) # 获取文字的宽和高
    # 填充字符串  画布的大小 - 文字的大小 / 2  字符串居中
    draw.text(((width - font_width) / 2, (height - font_height) / 2), text, font=font, fill=cls.fontcolor)
    # 如果需要干扰线
    if cls.draw_line:
        # 遍历 line_number ,就是画线的条数
        for x in range(0, cls.line_number):
            cls.__gene_line(draw, width, height)
    # 如果需要绘制噪点
    if cls.draw_point:
        cls.__gene_point(draw, 10, width, height)
    
    return (text,image)

② 读取图形验证码

在 django.http 模块中定义了 HttpResponse 对象的API。

from django.http import HttpResponse
属性
  • content:表示返回的内容,字符串类型
  • charset:表示response采用的编码字符集,字符串类型
  • status_code:响应的HTTP响应状态码
  • content-type:指定输出的MIME类型
方法
  • init :使用页内容实例化HttpResponse对象
  • write(content):以文件的方式写
  • flush():以文件的方式输出缓存区
  • set_cookie(key, value='', max_age=None, expires=None):设置Cookie
    • key、value 都是字符串类型;
    • max_age 是一个整数,表示在指定秒数后过期;
    • expires 是一个 datetime 或 timedelta 对象,会话将在这个指定的日期/时间过期,注意 datetime 和 timedelta 值只有在使用 PickleSerializer 时才可序列化;
    • max_age 与 expires 二选一;
    • 如果不指定过期时间,则两个星期后过期。
  • delete_cookie(key):删除指定的key的Cookie,如果key不存在则什么也不发生。

调用图形验证码生成类

from io import BytesIO
from utils.captcha.hycaptcha import Captcha
def img_captcha(request):
    text, image = Captcha.gene_code()
    # 字节流 image 不是一个HttpRsponse 可以识别的对象
    # 要将image 变成一个数据流才能放到HttpRsponse中
    # BytesIO() 相当于一个管道,可以用来储存 字节流
    out = BytesIO()
    image.save(out, 'png')
    # 将文件指针设置到0
    out.seek(0)
    # content_type 数据类型
    response = HttpResponse(content_type='image/png')
    # 从文件指针开始读
    response.write(out.read())
    # 返回文件指针在哪个位置 得到文件大小
    response['Content-length'] = out.tell()
    # 将图形验证码保留在 session
    request.session['img_captcha'] = text
    return response
urlpatterns = [
  path("img_captcha/", views.img_captcha, name='img_captcha'),
]
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据云团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 图像缩放操作
    • 属性
      • 方法
      相关产品与服务
      验证码
      腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档