中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

爬蟲Python怎么識別驗證碼

發布時間:2021-08-27 20:56:37 來源:億速云 閱讀:177 作者:chen 欄目:開發技術

本篇內容主要講解“爬蟲Python怎么識別驗證碼”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“爬蟲Python怎么識別驗證碼”吧!

目錄
  • 爬蟲Python驗證碼識別

    •  1、批量下載驗證碼圖片

    • 2、識別代碼看看效果

    •  3、折騰降噪、去干擾

爬蟲Python驗證碼識別

前言:

二值化、普通降噪、8鄰域降噪
tesseract、tesserocr、PIL

 1、批量下載驗證碼圖片

import shutil
import requests
from loguru import logger

for i in range(100):
    url = 'http://xxxx/create/validate/image'
    response = requests.get(url, stream=True)
    with open(f'./imgs/{i}.png', 'wb') as out_file:
        response.raw.decode_content = True
        shutil.copyfileobj(response.raw, out_file)
        logger.info(f"download {i}.png successfully.")
    del response

爬蟲Python怎么識別驗證碼

爬蟲Python怎么識別驗證碼

2、識別代碼看看效果

from PIL import Image
import tesserocr
img = Image.open("./imgs/98.png")
img.show()
img_l = img.convert("L")# 灰階圖
img_l.show()
verify_code1 = tesserocr.image_to_text(img)
verify_code2 = tesserocr.image_to_text(img_l)
print(f"verify_code1:{verify_code1}")
print(f"verify_code2:{verify_code2}")

爬蟲Python怎么識別驗證碼

爬蟲Python怎么識別驗證碼

毫無疑問,無論是原圖還是灰階圖,一無所有。

 3、折騰降噪、去干擾

Python圖片驗證碼降噪 - 8鄰域降噪

from PIL import Image
# https://www.cnblogs.com/jhao/p/10345853.html Python圖片驗證碼降噪 — 8鄰域降噪

 
def noise_remove_pil(image_name, k):
    """
    8鄰域降噪
    Args:
        image_name: 圖片文件命名
        k: 判斷閾值
    Returns:
    """

    def calculate_noise_count(img_obj, w, h):
        """
        計算鄰域非白色的個數
        Args:
            img_obj: img obj
            w: width
            h: height
        Returns:
            count (int)
        """
        count = 0
        width, height = img_obj.size
        for _w_ in [w - 1, w, w + 1]:
            for _h_ in [h - 1, h, h + 1]:
                if _w_ > width - 1:
                    continue
                if _h_ > height - 1:
                    continue
                if _w_ == w and _h_ == h:
                    continue
                if img_obj.getpixel((_w_, _h_)) < 230:  # 這里因為是灰度圖像,設置小于230為非白色
                    count += 1
        return count

    img = Image.open(image_name)
    # 灰度
    gray_img = img.convert('L')

    w, h = gray_img.size
    for _w in range(w):
        for _h in range(h):
            if _w == 0 or _h == 0:
                gray_img.putpixel((_w, _h), 255)
                continue
            # 計算鄰域非白色的個數
            pixel = gray_img.getpixel((_w, _h))
            if pixel == 255:
                continue

            if calculate_noise_count(gray_img, _w, _h) < k:
                gray_img.putpixel((_w, _h), 255)
    return gray_img


if __name__ == '__main__':
    image = noise_remove_pil("./imgs/1.png", 4)
    image.show()

看下圖效果:

爬蟲Python怎么識別驗證碼

這樣差不多了,不過還可以提升

提升新思路:

爬蟲Python怎么識別驗證碼

這邊的干擾線是從某個點發出來的紅色線條,

其實我只需要把紅色的像素點都干掉,這個線條也會被去掉。

from PIL import Image
import tesserocr
img = Image.open("./imgs/98.png")
img.show()

# 嘗試去掉紅像素點
w, h = img.size
for _w in range(w):
    for _h in range(h):
        o_pixel = img.getpixel((_w, _h))
        if o_pixel == (255, 0, 0):
            img.putpixel((_w, _h), (255, 255, 255))
img.show()

img_l = img.convert("L")
# img_l.show()
verify_code1 = tesserocr.image_to_text(img)
verify_code2 = tesserocr.image_to_text(img_l)
print(f"verify_code1:{verify_code1}")
print(f"verify_code2:{verify_code2}")

看起來OK,上面還有零星的藍色像素掉,也可以用同樣的方法一起去掉。

爬蟲Python怎么識別驗證碼

爬蟲Python怎么識別驗證碼

甚至OCR都直接出效果了
好了,完結撒花。
不過,后面發現,有些紅色線段和藍色點,是和驗證碼重合的。
這個時候,如果直接填成白色,就容易把字母切開,導致識別效果變差。
當前點是紅色或者藍色,判斷周圍點是不是超過兩個像素點是黑色。
是,填充為黑色。
否,填充成白色。

最終完整代碼:

from PIL import Image
import tesserocr
from loguru import logger


class VerfyCodeOCR():
    def __init__(self) -> None:
        pass

    def ocr(self, img):
        """ 驗證碼OCR

        Args:
            img (img): imgObject/imgPath

        Returns:
            [string]: 識別結果
        """
        img_obj = Image.open(img) if type(img) == str else img
        self._remove_pil(img_obj)
        verify_code = tesserocr.image_to_text(img_obj)
        return verify_code.replace("\n", "").strip()

    def _get_p_black_count(self, img: Image, _w: int, _h: int):
        """ 獲取當前位置周圍像素點中黑色元素的個數

        Args:
            img (img): 圖像信息
            _w (int): w坐標
            _h (int): h坐標

        Returns:
            int: 個數
        """
        w, h = img.size
        p_round_items = []
        # 超過了橫縱坐標
        if _w == 0 or _w == w-1 or 0 == _h or _h == h-1:
            return 0
        p_round_items = [img.getpixel(
            (_w, _h-1)), img.getpixel((_w, _h+1)), img.getpixel((_w-1, _h)), img.getpixel((_w+1, _h))]
        p_black_count = 0
        for p_item in p_round_items:
            if p_item == (0, 0, 0):
                p_black_count = p_black_count+1
        return p_black_count

    def _remove_pil(self, img: Image):
        """清理干擾識別的線條和噪點

        Args:
            img (img): 圖像對象

        Returns:
            [img]: 被清理過的圖像對象
        """
        w, h = img.size
        for _w in range(w):
            for _h in range(h):
                o_pixel = img.getpixel((_w, _h))
                # 當前像素點是紅色(線段) 或者 綠色(噪點)
                if o_pixel == (255, 0, 0) or o_pixel == (0, 0, 255):
                    # 周圍黑色數量大于2,則把當前像素點填成黑色;否則用白色覆蓋
                    p_black_count = self._get_p_black_count(img, _w, _h)
                    if p_black_count >= 2:
                        img.putpixel((_w, _h), (0, 0, 0))
                    else:
                        img.putpixel((_w, _h), (255, 255, 255))

        logger.info(f"_remove_pil finish.")
        # img.show()
        return img


if __name__ == '__main__':
    verfyCodeOCR = VerfyCodeOCR()
    img_path = "./imgs/51.png"
    img= Image.open(img_path)
    img.show()
    ocr_result = verfyCodeOCR.ocr(img)
    img.show()
    logger.info(ocr_result)

爬蟲Python怎么識別驗證碼

到此,相信大家對“爬蟲Python怎么識別驗證碼”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沙河市| 罗甸县| 离岛区| 徐闻县| 招远市| 桐乡市| 开鲁县| 中宁县| 团风县| 永济市| 通渭县| 安阳县| 吴桥县| 德江县| 定陶县| 葵青区| 芜湖市| 井研县| 邢台县| 扬州市| 金寨县| 钟山县| 清新县| 陇南市| 贵南县| 嘉黎县| 甘南县| 吴江市| 苏尼特左旗| 东莞市| 芦溪县| 诏安县| 黄大仙区| 温泉县| 武邑县| 娱乐| 渝中区| 内乡县| 辛集市| 资源县| 青铜峡市|