一、前言
本實(shí)驗(yàn)將通過一個簡單的例子來講解破解驗(yàn)證碼的原理,將學(xué)習(xí)和實(shí)踐以下知識點(diǎn):
Python基本知識
PIL模塊的使用
二、實(shí)例詳解
安裝 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
下載實(shí)驗(yàn)用的文件:
$ wget http://labfile.oss.aliyuncs.com/courses/364/python_captcha.zip$ unzip python_captcha.zip$ cd python_captcha
這是我們實(shí)驗(yàn)使用的驗(yàn)證碼 captcha.gif
提取文本圖片
在工作目錄下新建 crack.py 文件,進(jìn)行編輯。
#-*- coding:utf8 -*-from PIL import Imageim = Image.open("captcha.gif")#(將圖片轉(zhuǎn)換為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]
顏色直方圖的每一位數(shù)字都代表了在圖片中含有對應(yīng)位的顏色的像素的數(shù)量。
每個像素點(diǎn)可表現(xiàn)256種顏色,你會發(fā)現(xiàn)白點(diǎn)是最多(白色序號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 才是我們需要的紅色和灰色,可以通過這一訊息構(gòu)造一種黑白二值圖片。
#-*- 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()
新聞熱點(diǎn)
疑難解答
圖片精選