一、前言
本实验将通过一个简单的例子来讲解破解验证码的原理,将学习和实践以下知识点:
Python基本知识
PIL模块的使用
二、实例详解
安装 pillow(PIL)库:
$ sudo apt-get update$ sudo apt-get install python-dev$ sudo apt-get install libtiff5-dev libjpeg8-dev zlib1g-dev /libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python-tk$ sudo pip install pillow
下载实验用的文件:
$ wget http://labfile.oss.aliyuncs.com/courses/364/python_captcha.zip$ unzip python_captcha.zip$ cd python_captcha
这是我们实验使用的验证码 captcha.gif
提取文本图片
在工作目录下新建 crack.py 文件,进行编辑。
#-*- coding:utf8 -*-from PIL import Imageim = Image.open("captcha.gif")#(将图片转换为8位像素模式)im = im.convert("P")#打印颜色直方图print im.histogram()
输出:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0 , 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 2, 0, 1, 0, 0, 1, 0, 2, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 3, 1, 3, 3, 0, 0, 0, 0, 0, 0, 1, 0, 3, 2, 132, 1, 1, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0 , 1, 0, 1, 0, 0, 8, 1, 0, 0, 0, 0, 1, 6, 0, 2, 0, 0, 0, 0, 18, 1, 1, 1, 1, 1, 2, 365, 115, 0, 1, 0, 0, 0, 135, 186, 0, 0, 1, 0, 0, 0, 116, 3, 0, 0, 0, 0, 0, 21, 1, 1, 0, 0, 0, 2, 10, 2, 0, 0, 0, 0, 2, 10, 0, 0, 0, 0, 1, 0, 625]
颜色直方图的每一位数字都代表了在图片中含有对应位的颜色的像素的数量。
每个像素点可表现256种颜色,你会发现白点是最多(白色序号255的位置,也就是最后一位,可以看到,有625个白色像素)。红像素在序号200左右,我们可以通过排序,得到有用的颜色。
his = im.histogram()values = {}for i in range(256): values[i] = his[i]for j,k in sorted(values.items(),key=lambda x:x[1],reverse = True)[:10]: print j,k
输出:
255 625212 365220 186219 135169 132227 116213 115234 21205 18184 15
我们得到了图片中最多的10种颜色,其中 220 与 227 才是我们需要的红色和灰色,可以通过这一讯息构造一种黑白二值图片。
#-*- coding:utf8 -*-from PIL import Imageim = Image.open("captcha.gif")im = im.convert("P")im2 = Image.new("P",im.size,255)for x in range(im.size[1]): for y in range(im.size[0]): pix = im.getpixel((y,x)) if pix == 220 or pix == 227: # these are the numbers to get im2.putpixel((y,x),0)im2.show()
新闻热点
疑难解答