自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用 Python 生成并識(shí)別圖片驗(yàn)證碼

開(kāi)發(fā) 前端
?本次來(lái)分享一個(gè)關(guān)于驗(yàn)證碼的知識(shí),在登錄網(wǎng)站時(shí),為了確保是人在操作,一般會(huì)要求輸入圖片上的驗(yàn)證碼。那么這個(gè)驗(yàn)證碼要怎么生成呢?以及在做爬蟲(chóng)的時(shí)候,怎么用機(jī)器來(lái)識(shí)別呢?

本次來(lái)分享一個(gè)關(guān)于驗(yàn)證碼的知識(shí),在登錄網(wǎng)站時(shí),為了確保是人在操作,一般會(huì)要求輸入圖片上的驗(yàn)證碼。那么這個(gè)驗(yàn)證碼要怎么生成呢?以及在做爬蟲(chóng)的時(shí)候,怎么用機(jī)器來(lái)識(shí)別呢?

圍繞著這兩個(gè)問(wèn)題,我們開(kāi)始今天的內(nèi)容。

生成驗(yàn)證碼

所謂驗(yàn)證碼就是一張圖片,圖片上有一些數(shù)字和字母。所以我們只要生成一張圖片,然后在圖片上寫一些內(nèi)容即可。

使用 PIL 模塊可以非常方便做到這一點(diǎn),沒(méi)有安裝的話,需要執(zhí)行 pip install pillow。

from random import randint, sample
import string
from PIL import Image, ImageFont, ImageDraw


# 隨機(jī)生成畫(huà)板顏色
bg_color = randint(0, 255), randint(0, 255), randint(0, 255)
# 定義畫(huà)板的寬和高
width, height = 200, 80
# 創(chuàng)建畫(huà)板對(duì)象
im = Image.new("RGB", (width, height), bg_color)
# 創(chuàng)建畫(huà)筆對(duì)象,接收畫(huà)板對(duì)象
# 這樣一來(lái),畫(huà)筆所畫(huà)的內(nèi)容都會(huì)顯示在畫(huà)板上
draw = ImageDraw.Draw(im)
# 繪制噪點(diǎn),噪點(diǎn)的數(shù)量一般為 width * height * 0.1
for _ in range(int(width * height * 0.1)):
    # 噪點(diǎn)的橫縱坐標(biāo)
    point_pos = randint(0, width), randint(0, height)
    # 噪點(diǎn)的顏色,盡量也是隨機(jī)的
    point_color = randint(0, 255), randint(0, 255), randint(0, 255)
    # 繪制
    draw.point(point_pos, point_color)

# 查看繪制的圖片
im.show()

執(zhí)行代碼,會(huì)生成圖片,我們看一下長(zhǎng)什么樣子。

圖片圖片

可以看到噪點(diǎn)此刻繪制出來(lái)了,再為其繪制幾條直線和曲線。

# 直線的長(zhǎng)度要從畫(huà)板的左邊到畫(huà)板的右邊
# 因此左端點(diǎn)要在畫(huà)板左側(cè)上下變化,右端點(diǎn)要在畫(huà)板右側(cè)上下變化
for _ in range(5):
    left_pos = 0, randint(0, height)
    right_pos = width, randint(0, height)
    line_color = randint(0, 255), randint(0, 255), randint(0, 255)
    # 繪制直線
    draw.line([left_pos, right_pos], line_color)

# 繪制曲線,這里繪制的是一個(gè)超出畫(huà)板的大圓
# 這樣在畫(huà)板上顯示的部分只是大圓的一條弧,看起來(lái)就像是一條曲線
for _ in range(5):
    left_pos = (-100, -100)
    right_pos = (width * 5, randint(0, height))
    arc_color = randint(0, 255), randint(0, 255), randint(0, 255)
    draw.arc([left_pos, right_pos], 0, 360, arc_color)

# 查看一下,繪制的圖形長(zhǎng)什么樣子
im.show()

直線和曲線也繪制好了,看下效果。

圖片圖片

效果還是不錯(cuò)的,最后我們來(lái)繪制文字。

# 驗(yàn)證碼是由文字和數(shù)字組成,先來(lái)獲取所有的數(shù)字和字母
alpha_digit = string.ascii_letters + string.digits
# 驗(yàn)證碼一般是四個(gè)字符,從里面隨機(jī)選取4個(gè)
verify_code = sample(alpha_digit, 4)
# 生成字體對(duì)象
font = ImageFont.truetype("/System/Library/Fonts/Courier.ttc", 40)
# 為四個(gè)字符創(chuàng)建四種顏色
text_color = [(randint(0, 255), randint(0, 255), randint(0, 255))
              for _ in range(4)]
# 繪制文字
# 注意:坐標(biāo)加上字體的寬度不要超出畫(huà)板,否則顯示不全
draw.text((10, 10), verify_code[0], fill=text_color[0], fnotallow=font)
draw.text((60, 25), verify_code[1], fill=text_color[1], fnotallow=font)
draw.text((110, 15), verify_code[2], fill=text_color[2], fnotallow=font)
draw.text((150, 25), verify_code[3], fill=text_color[3], fnotallow=font)

# 繪制完成,最后再查看一下
im.show()

到此我們的驗(yàn)證碼就生成完畢了,那么效果如何呢?我們查看一下。

圖片圖片

整體來(lái)看還湊合,你也可以對(duì)背景色,以及文字的顏色進(jìn)行調(diào)整。如果覺(jué)得背景里的噪點(diǎn)、線段不太好,也可以將它們?nèi)サ簟?/p>

最后再來(lái)說(shuō)說(shuō)保存,代碼中的 im.show() 實(shí)際上是打開(kāi)了一個(gè)臨時(shí)文件,我們?nèi)绾螌⑺4嫦聛?lái)呢?

# 可以輸入一個(gè)路徑,然后保存成指定的文件
# 不過(guò)更常見(jiàn)的做法是拿到圖片的字節(jié)流,然后直接對(duì)字節(jié)流進(jìn)行渲染
from io import BytesIO
buf = BytesIO()
im.save(buf, "png")
# 此時(shí)圖片內(nèi)容就保存在了 buf 中
print(buf.getvalue()[: 6] == b"\x89PNG\r\n")  # True

以上就是繪制驗(yàn)證碼的過(guò)程,代碼是分塊展示的,你可以將它們合在一起,測(cè)試一下。

識(shí)別驗(yàn)證碼

說(shuō)完了生成驗(yàn)證碼,那么如何識(shí)別驗(yàn)證碼呢?Python 有一個(gè)第三方庫(kù) ddddocr,可以幫我們識(shí)別,直接 pip install ddddocr 安裝即可。

我們目前已經(jīng)生成了一張驗(yàn)證碼:

圖片圖片

這里補(bǔ)充一句,我們上面生成的驗(yàn)證碼圖片,在顏色上設(shè)計(jì)的不太好,因?yàn)楸尘吧臀淖诸伾际请S機(jī)的,這就導(dǎo)致當(dāng)顏色相近時(shí),看不清文字內(nèi)容。

而當(dāng)文字顏色和背景色比較接近時(shí),ddddocr 識(shí)別的準(zhǔn)確率就會(huì)降低很多,特別是背景中還有噪點(diǎn)和線段作為干擾。不過(guò)一般來(lái)說(shuō)網(wǎng)站的驗(yàn)證碼圖片都是經(jīng)過(guò)設(shè)計(jì)的,背景色和文字顏色區(qū)別還是比較大的,所以不用擔(dān)心。

我們測(cè)試一下:

import ddddocr

with open("code.png", "rb") as f:
    data = f.read()

# show_ad 默認(rèn)為 True,執(zhí)行時(shí)會(huì)輸出一些廣告,我們不讓它輸出
ocr = ddddocr.DdddOcr(show_ad=False)
code = ocr.classification(data)
print(code)  # 7abf

結(jié)果沒(méi)有問(wèn)題,識(shí)別出來(lái)了。

以上就是關(guān)于圖片驗(yàn)證碼的一些內(nèi)容。

責(zé)任編輯:武曉燕 來(lái)源: 古明地覺(jué)的編程教室
相關(guān)推薦

2023-10-27 08:53:13

Python驗(yàn)證碼圖片識(shí)別

2012-05-24 15:41:38

PHP

2013-06-19 10:19:59

2021-07-22 10:25:07

JS驗(yàn)證碼前端

2020-12-29 05:33:03

Serverless驗(yàn)證碼架構(gòu)

2022-09-21 08:40:04

OCR技術(shù)驗(yàn)證碼

2009-08-06 16:30:58

C#代碼和驗(yàn)證碼圖片

2009-11-23 16:34:22

PHP GD庫(kù)

2021-09-09 08:55:50

Python項(xiàng)目驗(yàn)證碼

2022-05-11 07:41:31

Python驗(yàn)證碼

2021-06-16 06:58:09

TensorFlow識(shí)別驗(yàn)證碼

2009-06-26 15:17:27

jQuery

2015-03-18 10:41:34

圖片驗(yàn)證驗(yàn)證碼12306

2021-08-11 09:51:24

人工智能機(jī)器學(xué)習(xí)技術(shù)

2014-04-24 10:09:05

驗(yàn)證碼C#

2022-07-20 09:52:44

Go語(yǔ)言短信驗(yàn)證碼

2020-08-12 09:14:45

Python驗(yàn)證碼工具

2024-03-08 12:04:22

PythonPillow驗(yàn)證碼

2020-11-16 07:28:53

驗(yàn)證碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)