99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁(yè)精彩閱讀Python使用PIL庫(kù)實(shí)現(xiàn)驗(yàn)證碼圖片的方法
Python使用PIL庫(kù)實(shí)現(xiàn)驗(yàn)證碼圖片的方法
2017-08-15
收藏

Python使用PIL庫(kù)實(shí)現(xiàn)驗(yàn)證碼圖片的方法

本文實(shí)例講述了Python使用PIL庫(kù)實(shí)現(xiàn)驗(yàn)證碼圖片的方法。分享給大家供大家參考,具體如下:

現(xiàn)在的網(wǎng)頁(yè)中,為了防止機(jī)器人提交表單,圖片驗(yàn)證碼是很常見的應(yīng)對(duì)手段之一。這里就不詳細(xì)介紹了,相信大家都遇到過。

現(xiàn)在就給出用Python的PIL庫(kù)實(shí)現(xiàn)驗(yàn)證碼圖片的代碼。代碼中有詳細(xì)注釋。

#!/usr/bin/env python
#coding=utf-8
importrandom
fromPILimportImage, ImageDraw, ImageFont, ImageFilter
_letter_cases="abcdefghjkmnpqrstuvwxy"# 小寫字母,去除可能干擾的i,l,o,z
_upper_cases=_letter_cases.upper()# 大寫字母
_numbers=''.join(map(str,range(3,10)))# 數(shù)字
init_chars=''.join((_letter_cases, _upper_cases, _numbers))
defcreate_validate_code(size=(120,30),
             chars=init_chars,
             img_type="GIF",
             mode="RGB",
             bg_color=(255,255,255),
             fg_color=(0,0,255),
             font_size=18,
             font_type="ae_AlArabiya.ttf",
             length=4,
             draw_lines=True,
             n_line=(1,2),
             draw_points=True,
             point_chance=2):
  '''
  @todo: 生成驗(yàn)證碼圖片
  @param size: 圖片的大小,格式(寬,高),默認(rèn)為(120, 30)
  @param chars: 允許的字符集合,格式字符串
  @param img_type: 圖片保存的格式,默認(rèn)為GIF,可選的為GIF,JPEG,TIFF,PNG
  @param mode: 圖片模式,默認(rèn)為RGB
  @param bg_color: 背景顏色,默認(rèn)為白色
  @param fg_color: 前景色,驗(yàn)證碼字符顏色,默認(rèn)為藍(lán)色#0000FF
  @param font_size: 驗(yàn)證碼字體大小
  @param font_type: 驗(yàn)證碼字體,默認(rèn)為 ae_AlArabiya.ttf
  @param length: 驗(yàn)證碼字符個(gè)數(shù)
  @param draw_lines: 是否劃干擾線
  @param n_lines: 干擾線的條數(shù)范圍,格式元組,默認(rèn)為(1, 2),只有draw_lines為True時(shí)有效
  @param draw_points: 是否畫干擾點(diǎn)
  @param point_chance: 干擾點(diǎn)出現(xiàn)的概率,大小范圍[0, 100]
  @return: [0]: PIL Image實(shí)例
  @return: [1]: 驗(yàn)證碼圖片中的字符串
  '''
  width, height=size# 寬, 高
  img=Image.new(mode, size, bg_color)# 創(chuàng)建圖形
  draw=ImageDraw.Draw(img)# 創(chuàng)建畫筆
  defget_chars():
    '''生成給定長(zhǎng)度的字符串,返回列表格式'''
    returnrandom.sample(chars, length)
  defcreate_lines():
    '''繪制干擾線'''
    line_num=random.randint(*n_line)# 干擾線條數(shù)
    foriinrange(line_num):
      # 起始點(diǎn)
      begin=(random.randint(0, size[0]), random.randint(0, size[1]))
      #結(jié)束點(diǎn)
      end=(random.randint(0, size[0]), random.randint(0, size[1]))
      draw.line([begin, end], fill=(0,0,0))
  defcreate_points():
    '''繪制干擾點(diǎn)'''
    chance=min(100,max(0,int(point_chance)))# 大小限制在[0, 100]
    forwinxrange(width):
      forhinxrange(height):
        tmp=random.randint(0,100)
        iftmp >100-chance:
          draw.point((w, h), fill=(0,0,0))
  defcreate_strs():
    '''繪制驗(yàn)證碼字符'''
    c_chars=get_chars()
    strs=' %s '%' '.join(c_chars)# 每個(gè)字符前后以空格隔開
    font=ImageFont.truetype(font_type, font_size)
    font_width, font_height=font.getsize(strs)
    draw.text(((width-font_width)/3, (height-font_height)/3),
          strs, font=font, fill=fg_color)
    return''.join(c_chars)
  ifdraw_lines:
    create_lines()
  ifdraw_points:
    create_points()
  strs=create_strs()
  # 圖形扭曲參數(shù)
  params=[1-float(random.randint(1,2))/100,
       0,
       0,
       0,
       1-float(random.randint(1,10))/100,
       float(random.randint(1,2))/500,
       0.001,
       float(random.randint(1,2))/500
       ]
  img=img.transform(size, Image.PERSPECTIVE, params)# 創(chuàng)建扭曲
  img=img.filter(ImageFilter.EDGE_ENHANCE_MORE)# 濾鏡,邊界加強(qiáng)(閾值更大)
  returnimg, strs
if__name__=="__main__":
  code_img=create_validate_code()
  code_img.save("validate.gif","GIF")

最后結(jié)果返回一個(gè)元組,第一個(gè)返回值是Image類的實(shí)例,第二個(gè)參數(shù)是圖片中的字符串(比較是否正確的作用)。

最后結(jié)果返回一個(gè)元組,第一個(gè)返回值是Image類的實(shí)例,第二個(gè)參數(shù)是圖片中的字符串(比較是否正確的作用)。

需要提醒的是,如果在生成ImageFont.truetype實(shí)例的時(shí)候拋出IOError異常,有可能是運(yùn)行代碼的電腦沒有包含指定的字體,需要下載安裝。

生成的驗(yàn)證碼圖片效果:

這時(shí)候,細(xì)心的同學(xué)可能要問,如果每次生成驗(yàn)證碼,都要先保存生成的圖片,再顯示到頁(yè)面。這么做讓人太不能接受了。這個(gè)時(shí)候,我們需要使用python內(nèi)置的StringIO模塊,它有著類似file對(duì)象的行為,但是它操作的是內(nèi)存文件。于是,我們可以這么寫代碼:

try:
  importcStringIO as StringIO
exceptImportError:
  importStringIO
mstream=StringIO.StringIO()
img=create_validate_code()[0]
img.save(mstream,"GIF")
這樣,我們需要輸出的圖片的時(shí)候只要使用“mstream.getvalue()”即可。比如在Django里,我們首先定義這樣的url:
fromdjango.conf.urls.defaultsimport*
urlpatterns=patterns('example.views',
  url(r'^validate/$','validate', name='validate'),
)
在views中,我們把正確的字符串保存在session中,這樣當(dāng)用戶提交表單的時(shí)候,就可以和session中的正確字符串進(jìn)行比較。
fromdjango.shortcutsimportHttpResponse
fromvalidateimportcreate_validate_code
defvalidate(request):
  mstream=StringIO.StringIO()
  validate_code=create_validate_code()
  img=validate_code[0]
  img.save(mstream,"GIF")
  request.session['validate']=validate_code[1]
  returnHttpResponse(mstream.getvalue(),"image/gif")
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。


數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請(qǐng)參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }