用python编写验证码

作为一个用python的生信工程师,平时工作中除了用python来处理些文本文件和搭建流程,没事也想探索些其他有趣的功能。这几天就在网上学习了下如何用python编写验证码,感兴趣的同学也一起来学习下吧!

01

验证码的作用及干扰机制

在编写验证码之前,我们首先来了解下验证码是用来干嘛的吧:

验证码主要是为了防止暴力破解,爬虫模拟登陆以及各种键盘钩子进行登陆;验证码能起到干扰作用的机制主要是靠背景点或线条进行干扰,以及对文字进行扭曲。

02

Python编写验证码实战

我们先来看下采用python编写验证码的一个基本思路:

1.定义一张图片

2.创建画笔

3.绘制线条和点

4.绘制文字

5.定义扭曲的参数

6.使用滤镜

下面我们分步来看一下每一步的代码实现是怎样的吧(注:这里采用的是python2进行编写):

01

导入模块

import randomfrom PIL import Image,ImageDraw,ImageFont,ImageFilter

这里我们需要用到两个模块,random模块和PTL模块。random模块用来生成随机数,PIL是一个用来处理图片文件的python第三方模块。PIL没有安装的小伙伴可以采用pip install PIL进行安装。PIL中的Image类负责处理图片,ImageDraw负责处理画笔, ImageFont负责处理字体,ImageFilter负责处理滤镜。

02

定义一张图片

img = Image.new("RGB",(150,50),(255,255,255))

这里需要用到三个参数,分别代表我们采用RGB颜色模式,图片的大小,具体的图片颜色。

03

创建画笔

draw = ImageDraw.Draw(img)

04

绘制线条和点

绘制线条

for i in range(random.randint(1,10)):
    draw.line(    
#在绘制线条时:每条线有两个点,每个点靠x,y两个值来确定位置       [
            ( random.randint(1,150),random.randint(1,150)),( 
random.randint(1,150),random.randint(1,150))
        ],
 fill = (0,0,0)  )

这里random.randint(1,10)函数用来生成1-10之间的随机数,draw.line是用来绘制线条的函数,由于一条线是由两个点组成,所以这里我们采用列表来储存线条的起止坐标。由于验证码中线条的作用就是起干扰作用,所以我们需要绘制出来的线条是没有规律的。这里循环用以生成线条的条数以及线条的起止坐标都采用random函数来随机生成。fill用来给出线条的RGB颜色。

绘制点

for i in range(2000):
draw.point(
        (random.randint(1,150),random.randint(1,150)),
                fill =(0,0,0)
            )

同理,我们可以绘制随机坐标的点,这里可以用循环控制绘制点的数量。

05

绘制文字

fontList = list("abdfkjfalemvcjierASDFGHJKLQW123456789")
c_chars = " ".join(random.sample(fontList,5)
#random.sample是在指定的列表当中随机取出指定个元素
font = ImageFont.truetype("simsun.ttc",26)
draw.text((5,5),c_chars,font=font,fill="green")

接下来我们就要绘制显示在验证码上的文字啦,在绘制文字的时候我们要考虑两点,首先我们生成的文字是要随机产生的,另外文字的个数需要是固定的。

这里我们首先利用fontList变量来定义要生成的随机数的字母和数字,接着我们要从定义的随机数列表当中取出指定个数的随机数。这里就要用到random.sample这个函数啦,函数后面接的参数就是取出的随机数的个数,其后我们用join函数将取出的随机数列表连接成字符串。随后用ImageFont.truetype定义字体,函数的第一个参数代表字体类别,第二个参数代表字体大小。最后采用draw.text进行文字的最终绘制,这里第一个参数代表文字的位置,距离上和左方的距离,第二个参数代表文字的内容,第三个参数代表字体,第四个参数定义字体的颜色。

06

定义扭曲参数

params = [1 - float(random.randint(1,2))/100,
          0,
          0,
          0,
          1 - float(random.randint(1,2))/100,
          float(random.randint(1,2))/500,
          0.001,
          float(random.randint(1,1))/500,
          ]

这里的参数有点多,这里就不详细介绍每个数值的含义啦,感兴趣的小伙伴可以自行百度搜索一下。

07

使用滤镜

img = img.transform((150,50),Image.PERSPECTIVE,params)  # 创建扭曲
"""
第一个参数:扭曲的范围,
第二个参数:扭曲的样式,
第三个参数:扭曲的参数
"""
img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) #滤镜,边界加强(阈值更大)
img.show()

接下来我们就要使用滤镜来对文字进行扭曲,首先使用img.transform这个函数来创建扭曲,其中的三个参数,分别代表扭曲的范围、扭曲的样式、扭曲的参数,接着使用img.filter来进行扭曲。

最后我们来看下生成的效果吧:

是不是很简单呢,上述代码我们也可以封装成函数进行编写,感兴趣的小伙伴们可以自己动手试下哦。

我们在学习python的过程中可以多找一些自己感兴趣的项目来练习提高自己的编程能力,比如多练习下生信技能树中的生信编程题,也可以找一些自己感兴趣的应用来学习,比如试着用爬虫爬取自己感兴趣的内容,也可以试着用python写一些小游戏玩玩,人生苦短,我用python,让我们一起在学习练习中进步吧!

原文发布于微信公众号 - 生信技能树(biotrainee)

原文发表时间:2017-09-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏肖蕾的博客

第十四章:TouchPadTouchPadStyleTouchPad控件

API定义:TouchPad的样式 用法:public TouchpadStyle(Drawable background, Drawable knob) ...

522
来自专栏练小习的专栏

SVG图形绘制入门第一弹

之前很长一段时间,我是不重视SVG的,认为他就是在AI里画画,然后导出来做个矢量图标。直到我在上家公司遇到图表的绘制,因为不会写不得已而拿插件实现,而插件绘制的...

2087
来自专栏转载gongluck的CSDN博客

GDI透明贴图

网上下载的图片,有一些会有水印。水印的实现可以用透明贴图来做。透明贴图就是让两张图片合并的时候,重叠的部分中使一些颜色不显示,从而达到透明的效果。 如果用GDI...

3936
来自专栏菩提树下的杨过

Matplotlib新手上路(上)

matplotlib是python里用于绘图的专用包,功能十分强大。下面介绍一些最基本的用法: 一、最基本的划线 先来一个简单的示例,代码如下,已经加了注释: ...

26710
来自专栏税国龙的专栏

我们来用 D3.js 画个饼图

最近在做腾讯云大数据可视化项目,天天跟各种柱状图、饼图、面积图等打交道。 饼图能直观的表现一堆数据中各项所占比例,是非常常见的图表之一。本文尝试来讲讲如何在浏览...

7297
来自专栏极客猴

Python 绘图,我只用 Matplotlib(三)—— 柱状图

上篇文章,我已经讲解绘制图像大致步骤,接下来的系列文章将分别对各种图形做讲解。其实就是了解各个图种的绘图 API。文章就讲解第一种图形,柱状图。

662
来自专栏IMWeb前端团队

这个问题你应该很熟悉,然后懵逼,然后放弃

今天早晨决定写这篇博文,但是晚上回家的时候,突然一道闪电从脑海劈过,于是临时决定将这个熟悉然后到懵逼最后到放弃的问题分为两部分。第一部分为抛出问题,诚邀各路英雄...

1620
来自专栏肖洒的博客

OpenCV学习笔记(Python)

警告: 就算图像的路径是错的, OpenCV 也不会提醒你的,但是当你使用命 令print img时得到的结果是None。

893
来自专栏hightopo

基于 HTML5 WebGL 的 3D 网络拓扑结构图

1362
来自专栏数据小魔方

excel函数入门须知——绝对引用与相对引用

今天给大家讲解excel函数入门必备知识——绝对引用与相对引用! ▽ 别怪小魔方大过年的污染大家心情 不知道是哪根筋不对 就是这么勤劳、敬业 今天给大家讲解ex...

2696

扫描关注云+社区