본문 바로가기
Development/Python

[Python] 파이썬 CAPTCHA 만들기

by 선인장 🌵 2023. 12. 3.
728x90
728x90

[Python] 파이썬 CAPTCHA 만들기

개발을 하다 보면 Captcha를 적용해야 하는 경우가 있다. 

물론 Google reCaptcha 혹은 Naver Captcha와 같이 이미 제공을 하는 곳이 많이 있다. 

 

reCAPTCHA  |  Google for Developers

스팸 및 악용으로부터 사이트 보호

developers.google.com

 

NAVER CLOUD PLATFORM

cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification

www.ncloud.com

하지만 제공하는 것을 모든 환경에서 사용을 할 수 없기 때문에 간단히 파이썬을 이용하여 Captcha를 만들어 보고자 한다.

[Python] 파이썬 CAPTCHA 만들기

728x90

1. captcha 라이브러리 설치

우선 사용을 위해서는 captcha 라이브러리를 설치해야 한다.

설치 방법은 pip 명령어를 통해서 아래와 같이 쉽게 설치가 가능하다.

  • $ pip install captcha
# pip를 이용한 captcha 라이브러리 설치

$ pip install captcha
Collecting captcha
  Using cached captcha-0.5.0-py3-none-any.whl.metadata (2.1 kB)
Requirement already satisfied: Pillow in /Users/happylie/.pyenv/versions/3.11.0/envs/venv.python_ex/lib/python3.11/site-packages (from captcha) (9.3.0)
Using cached captcha-0.5.0-py3-none-any.whl (102 kB)
Installing collected packages: captcha
Successfully installed captcha-0.5.0

$ pip freeze | grep captcha
captcha==0.5.0
 

captcha

A captcha library that generates audio and image CAPTCHAs.

pypi.org

2. captcha 라이브러리 이용하기

이제 captcha 라이브러리를 설치했으면 파이썬 코드를 이용하여 음성(Audio) captcha와 이미지(Image) captcha를 만들어 보도록 하자.

2.1 음성(Audio) captcha 만들기

이제 첫 번째로 간단하게 음성(Audio) captcha를 만들어 보도록 하자.

음성의 경우는 숫자만 가능하니 참고하도록 하자.

# Python Example Code
# Audio captcha

# -*- coding: utf-8 -*-
from captcha.audio import AudioCaptcha

audio = AudioCaptcha()

captcha_text = '1234'

audio.write(captcha_text, 'sample/1234.wav')

1234.wav
0.08MB

2.2 이미지(Image) captcha 만들기

그럼 두 번째로 간단하게 이미지(Image) captcha를 만들어 보도록 하자.

이미지 captcha의 경우 두 가지 방식으로 사용이 가능하다.

  1. 이미지 파일로 바로 저장하는 방법
  2. Base64를 통해서 이미지를 data로 만들어 String을 통해서 사용하는 방법
# Python Example Code
# Image captcha

# -*- coding: utf-8 -*-
import io
import base64
from captcha.image import ImageCaptcha

image = ImageCaptcha()

captcha_text = '1234'

image.write(captcha_text, 'sample/1234.png')

data = image.generate(captcha_text)
image_data_b64 = "data:image/png;base64," + base64.b64encode(io.BytesIO(data.read()).getvalue()).decode(
            "utf-8")

print(image_data_b64)



### Result ###
data:image/png;base64,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

1234.png
0.01MB
Base64를 이용한 String 사용 방법

728x90

3. 기본 코드를 이용한 간단한 라이브러리 제작

아래 코드는 기본 코드를 이용해서 좀 더 쉽게 사용하기 위해서 자체적으로 작성한 코드이다.

해당 코드에 대해서 간단하게 설명을 하자면, 우선 음성(Audio) / 이미지(Image) 모두 불러서 사용할 수 있도록 되어있다. 

여기서 음성(Audio)의 경우 숫자로만 이뤄져야 음성(Audio) 파일을 만들 수 있기 때문에 random code 부분에 captcha_type을 추가해 놓았다. 

그리고 이미지(Image) captcha의 경우는 이미지 크기, 이미지에 들어가 글자의 크기를 정할 수 있도록 설정해 놓았다. 

# -*- coding: utf-8 -*-
import random
import io
import base64
import string
from captcha.image import ImageCaptcha
from captcha.audio import AudioCaptcha


def _random_code(length=8, captcha_type=None):
    """
    Random Code Generate
    :param length: Default Length 8
    :captcha_type: None, audio
    :return:
    """
    custom_punctuation = '#%&?$'
    custom_lowercase = 'abdefghjqrt'
    custom_uppercase = 'ABDEFGHJLQRT'
    custom_digits = '2345678'
    if captcha_type == 'audio':
        return "".join(random.choice(string.digits) for _ in range(length))
    allowed_code = custom_digits + custom_uppercase + custom_lowercase + custom_punctuation
    return "".join(random.choice(allowed_code) for _ in range(length))


class MakeCaptchaAudio:
    def __init__(self):
        self.audio = AudioCaptcha()
        self.captcha_text = _random_code(captcha_type="audio")
        self.ret = ""

    def set_save_audio_file(self) -> bool:
        """
        Set Captcha Audio File Save(File Type : WAV)
        :return:
        """
        try:
            self.audio.write(self.captcha_text, f'sample/output.wav')
            return True
        except Exception as err:
            return False


class MakeCaptchaImg:
    def __init__(self):
        self.width: int = 250
        self.height: int = 100
        self.font_sizes: tuple = (50, 58, 64)
        self.image = ImageCaptcha(self.width, self.height, font_sizes=self.font_sizes)
        self.audio = AudioCaptcha()
        self.captcha_text = _random_code()
        self.ret = ""

    def captcha_valid(self, text) -> bool:
        """
        Captcha Valid
        :param text:
        :return:
        """
        if self.captcha_text != text:
            return False
        return True

    def get_base64_image_data(self):
        """
        Get Captcha Base64 Image Data(File Type : PNG)
        :return:
        """
        image_data = self.image.generate(self.captcha_text)
        image_data_b64 = "data:image/png;base64," + base64.b64encode(io.BytesIO(image_data.read()).getvalue()).decode(
            "utf-8")
        return image_data_b64

    def set_save_image_file(self) -> bool:
        """
        Set Captcha Image File Save(File Type : PNG)
        :return:
        """
        try:
            self.image.write(self.captcha_text, f'sample/output.png')
            return True
        except Exception as err:
            return False


if __name__ == "__main__":
    # CAPTCHA Audio
    captcha_audio = MakeCaptchaAudio()
    print(f'CAPTCHA Text: {captcha_audio.captcha_text}')
    print(f'Save Audio: {captcha_audio.set_save_audio_file()}')

    # CAPTCHA Image
    captcha_img = MakeCaptchaImg()
    print(f'CAPTCHA Text: {captcha_img.captcha_text}')
    print(f'Base64 Image: {captcha_img.get_base64_image_data()}')
    print(f'Save Image: {captcha_img.set_save_image_file()}')
    print(f'CAPTCHA Valid: {captcha_img.captcha_valid(captcha_img.captcha_text)}')
    print(f'CAPTCHA Valid: {captcha_img.captcha_valid("1234")}')




### Result ###
CAPTCHA Text: 92992991
Save Audio: True
CAPTCHA Text: %dDg62dh
Base64 Image : data:image/png;base64,iVBOR...QmCC
Save Image: True
CAPTCHA Valid: True
CAPTCHA Valid: False

4. 예제 코드

captcha 라이브러리를 이용하여 음성(Audio) / 이미지(Image) captcha를 만들어 보는 방법을 알아보았다.

위에 나온 예제 파일은 Github에 올려놓았다. 

해당 내용에 대해서 문의가 있거나 궁금한 내용이 있다면 Github Issus 혹은 댓글로 남겨주면 최대한 빠르게 답변을 할 수 있도록 하겠다.

 

GitHub - happylie/python-example-code: Python Example Code

Python Example Code. Contribute to happylie/python-example-code development by creating an account on GitHub.

github.com

728x90
728x90


🌵댓글

 

loading