圖片驗證碼:登陸網頁時,生成隨機圖片驗證碼,在網頁中顯示出來,並把驗證碼保存下來用以登陸判斷。
所用技術:tornado框架,自定義生成圖片驗證碼的python文件及其相應字體文件,io模塊,pillow模塊。
所用技術:tornado框架,自定義生成圖片驗證碼的python文件及其相應字體文件,io模塊,pillow模塊。
目錄結構:

啟動文件代碼如下:

1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 import tornado.web 4 import tornado.ioloop 5 import check_code #自定義文件 6 import io 7 8 list_code = [] 9 class LoginHandler(tornado.web.RequestHandler): 10 def get(self, *args, **kwargs): 11 self.render('login.html') 12 def post(self, *args, **kwargs): 13 user = self.get_argument('user') 14 validate = self.get_argument('validate') 15 print(validate) 16 if user == 'alex' and validate == list_code[0]: 17 self.write('用戶名和驗證碼通過') 18 else: 19 self.write('用戶名和驗證碼有一樣不通過') 20 21 class CheckCodeHandler(tornado.web.RequestHandler): 22 def get(self, *args, **kwargs): 23 img,code = check_code.create_validate_code() #生成驗證碼圖片,圖片保存在img,驗證碼保存在code 24 cc = io.BytesIO() #生成這個對象用以臨時存放數據 25 img.save(cc,'GIF') #把圖片以gif格式存放在cc里 26 print(code) 27 list_code.append(code) #把驗證碼追加到空列表里用以登陸時判斷,也可以放到cookie,secure_cookie,session里 28 print(list_code) 29 self.write(cc.getvalue()) #獲取圖片在頁面顯示出來 30 31 settings = { 32 'template_path':'view' 33 } 34 35 app = tornado.web.Application([ 36 ('/login',LoginHandler), 37 ('/checkcode',CheckCodeHandler) 38 ],**settings) 39 40 if __name__ == '__main__': 41 app.listen('8888') 42 tornado.ioloop.IOLoop.instance().start()
view目錄下的html代碼:

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <form action="/login" method="post"> 9 <input type="text" placeholder="用戶名" name="user"> 10 <p> 11 <input type="text" placeholder="填寫右側驗證碼" name="validate"> 12 <img src="/checkcode" onclick="Changecode()" id="validate_img"> 13 </p> 14 <input type="submit" value="提交"> #點擊提交后以post方式把表單name鍵值對提交到/login 15 </form> 16 <script> 17 function Changecode() { 18 var el = document.getElementById('validate_img'); 19 el.src += '?'; #獲取圖片標簽的src,給加上?再放回去,就會在不刷新網頁的基礎上重新以get方式訪問網頁 20 } 21 </script> 22 </body> 23 </html>
check_code.py :

1 #!/usr/bin/env python 2 #coding:utf-8 3 #check_code.py 4 5 import random 6 from PIL import Image, ImageDraw, ImageFont, ImageFilter 7 8 _letter_cases = "abcdefghjkmnpqrstuvwxy" # 小寫字母,去除可能干擾的i,l,o,z 9 _upper_cases = _letter_cases.upper() # 大寫字母 10 _numbers = ''.join(map(str, range(3, 10))) # 數字 11 init_chars = ''.join((_letter_cases, _upper_cases, _numbers)) 12 13 def create_validate_code(size=(120, 30), 14 chars=init_chars, 15 img_type="GIF", 16 mode="RGB", 17 bg_color=(255, 255, 255), 18 fg_color=(0, 0, 255), 19 font_size=18, 20 font_type="Monaco.ttf", 21 length=4, 22 draw_lines=True, 23 n_line=(1, 2), 24 draw_points=True, 25 point_chance = 2): 26 ''' 27 @todo: 生成驗證碼圖片 28 @param size: 圖片的大小,格式(寬,高),默認為(120, 30) 29 @param chars: 允許的字符集合,格式字符串 30 @param img_type: 圖片保存的格式,默認為GIF,可選的為GIF,JPEG,TIFF,PNG 31 @param mode: 圖片模式,默認為RGB 32 @param bg_color: 背景顏色,默認為白色 33 @param fg_color: 前景色,驗證碼字符顏色,默認為藍色#0000FF 34 @param font_size: 驗證碼字體大小 35 @param font_type: 驗證碼字體,默認為 ae_AlArabiya.ttf 36 @param length: 驗證碼字符個數 37 @param draw_lines: 是否划干擾線 38 @param n_lines: 干擾線的條數范圍,格式元組,默認為(1, 2),只有draw_lines為True時有效 39 @param draw_points: 是否畫干擾點 40 @param point_chance: 干擾點出現的概率,大小范圍[0, 100] 41 @return: [0]: PIL Image實例 42 @return: [1]: 驗證碼圖片中的字符串 43 ''' 44 45 width, height = size # 寬, 高 46 img = Image.new(mode, size, bg_color) # 創建圖形 47 draw = ImageDraw.Draw(img) # 創建畫筆 48 49 def get_chars(): 50 '''生成給定長度的字符串,返回列表格式''' 51 return random.sample(chars, length) 52 53 def create_lines(): 54 '''繪制干擾線''' 55 line_num = random.randint(*n_line) # 干擾線條數 56 57 for i in range(line_num): 58 # 起始點 59 begin = (random.randint(0, size[0]), random.randint(0, size[1])) 60 #結束點 61 end = (random.randint(0, size[0]), random.randint(0, size[1])) 62 draw.line([begin, end], fill=(0, 0, 0)) 63 64 def create_points(): 65 '''繪制干擾點''' 66 chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100] 67 68 for w in range(width): 69 for h in range(height): 70 tmp = random.randint(0, 100) 71 if tmp > 100 - chance: 72 draw.point((w, h), fill=(0, 0, 0)) 73 74 def create_strs(): 75 '''繪制驗證碼字符''' 76 c_chars = get_chars() 77 strs = ' %s ' % ' '.join(c_chars) # 每個字符前后以空格隔開 78 79 font = ImageFont.truetype(font_type, font_size) 80 font_width, font_height = font.getsize(strs) 81 82 draw.text(((width - font_width) / 3, (height - font_height) / 3), 83 strs, font=font, fill=fg_color) 84 85 return ''.join(c_chars) 86 87 if draw_lines: 88 create_lines() 89 if draw_points: 90 create_points() 91 strs = create_strs() 92 93 # 圖形扭曲參數 94 params = [1 - float(random.randint(1, 2)) / 100, 95 0, 96 0, 97 0, 98 1 - float(random.randint(1, 10)) / 100, 99 float(random.randint(1, 2)) / 500, 100 0.001, 101 float(random.randint(1, 2)) / 500 102 ] 103 img = img.transform(size, Image.PERSPECTIVE, params) # 創建扭曲 104 105 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 濾鏡,邊界加強(閾值更大) 106 107 return img, strs
check_code.py需要的相應字體文件:Monaco.ttf