SoFunction
Updated on 2024-11-12

Using Python to generate random CAPTCHA details

Lately it feels like I'm being defined as a robot by big data, and random web pages are jumping CAPTCHAs.

How to bypass captchas with python is a balding thing to do, the

I surrender! So today handily, I'm going to teach you how to write captcha codes to embarrass people and make their heads go bald.

Wrong, it actually teaches you how to generate captcha through python code~~

1. First, the environment

1. we need your computer has python3.4 or above version

Installing the PIL package

pip install pillow

3. Silently read once "life is short, I use python", and then open IDLE to start code!

2. Start code

1. Determine canvas size and background color

# Import the relevant drawing module
from PIL import Image, ImageDraw, ImageFont

# Setting the background color
bg_color = (100, 100, 255)

# Set canvas length and width (pixels)
width = 400
height = 100

# Generate a new canvas with settings
im = ('RGB',(width,height),bg_color)
# Show the canvas
()

The bg_color background color is set using the RGB color standard, if you don't like the background color you can adjust it yourself.

"Common RGB colors

After running the code:

2. Drawing characters on the background cloth

Let's start with the code.

from PIL import Image, ImageDraw, ImageFont


# Omit the code for the first step

# Create a brush object
draw = (im)
# captcha text
string = 'MSBC'
# Construct the font object
font = ('./', 90)
# font = ImageFont.load_default().font
# Construct font colors
fontcolor = (255, 100, 100)
# Drawing 4 words
((10, 2), string[0], font=font, fill=fontcolor)
((110, 2), string[1], font=font, fill=fontcolor)
((210, 2), string[2], font=font, fill=fontcolor)
((310, 2), string[3], font=font, fill=fontcolor)


# Release the brush
del draw
#Show Pictures
()

Code Analysis:

draw = (im)

Instantiate a pen on the im canvas.

font = ('./', 90)
# font = ImageFont.load_default().font

The first parameter is to set the font, I have downloaded a ttf font file here so I can use it, if there is no specified font file you can use the default # font = ImageFont.load_default().

The second parameter is the size of the font to draw, since our canvas is 400x100 so we'll set the font to 90x90 for aesthetics.

# Construct font colors
fontcolor = (255, 100, 100)

For the color of the font text, refer to the RGB setting of the canvas in the first step.

# Drawing 4 words
((10, 2), string[0], font=font, fill=fontcolor)
((110, 2), string[1], font=font, fill=fontcolor)
((210, 2), string[2], font=font, fill=fontcolor)
((310, 2), string[3], font=font, fill=fontcolor)

Here the function, as the name implies, is to start taking the paintbrush and start writing.

First parameter The coordinates of the write;

Second argument The word to write;

The third parameter The color of the word (as constructed above, you can also set it to one color for each word).

Run the code and see the results:

The effect is okay, but it always feels like something is missing?

3. Adding interference

Since it's a CAPTCHA, it's definitely going to be slightly harder to recognize, what's up with the one above that's so goofy and sweet?

In this step we need to import the random module because the interference is generated irregularly and randomly.

import random
from PIL import Image, ImageDraw, ImageFont

# Omit the first step of the code

# Omit the second step of the code

# Plotting noise with the point function
for i in range(0, 100):
    xy = ((0, width), (0, height))
    fill = ((0, 255), 255, (0, 255))
    (xy, fill=fill)
    
# Release the brush
del draw   
()

Code Analysis:

import random

Don't forget to import the random module

for i in range(0, 100):
    xy = ((0, width), (0, height))
    fill = (255, 255, 255)
    (xy, fill=fill)

A for loop that loops 100 times.

The xy variable is the value of the coordinates of the point where the interference is drawn.

Is the fill variable the color of the noise, or is it RGB?

The action of drawing dots

"The more times this for loop is performed, the more noise on the canvas will increase accordingly.

Run the code to see how the noise works:

It still feels a little goofy, so let's try looping it 1,000 times:

10,000 times!

That's enough.

4. Adding more interference

In this step I combine the individual parameters with the random module to make our CAPTCHA harder to recognize!

import random
from PIL import Image, ImageDraw, ImageFont


bg_color = ((20, 120), (20, 120), (150, 255))
width = 400
height = 100

im = ('RGB',(width,height),bg_color)
# Create a brush object
draw = (im)

# Construct the font object
font = ('./', 100)
# font = ImageFont.load_default().font
# Construct font colors
fontcolor = ((0, 255), (0, 255), (0, 255))
# Drawing 4 words
string = 'MSBC'
(((10, 30), ((0, 10))), string[0], font=font, fill=fontcolor)
(((90, 130), ((0, 10))), string[1], font=font, fill=fontcolor)
(((180, 230), ((0, 10))), string[2], font=font, fill=fontcolor)
(((270, 330), ((0, 10))), string[3], font=font, fill=fontcolor)

# Call the point() function of the brush to draw the noise.
for i in range(0, 10000):
    xy = ((0, width), (0, height))
    fill = ((0, 255), (0, 255), (0, 255))
    (xy, fill=fill)

# Release the brush
del draw
()

I combined the font color, noise color, and text position with the random module, and the result is shown below:

5. Captcha + random characters

In this step, we need to encapsulate the above code into a function, roughly refactoring the above code into.

# Use a for loop to generate text characters

# A function that generates a CAPTCHA image, the argument is the text generated above

# Call the Generate CAPTCHA Image function

Reconfigured:

import random
from PIL import Image, ImageDraw, ImageFont

string = ''
#4 randomly selected values as captcha codes
rand_str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
for i in range(0, 4):
    string += rand_str[(0, len(rand_str))]


def gen_verify_img(text):
    bg_color = ((20, 120), (20, 120), (150, 255))
    width = 400
    height = 100

    im = ('RGB',(width,height),bg_color)
    # Create a brush object
    draw = (im)

    # Construct the font object
    font = ('./', 100)
    # font = ImageFont.load_default().font
    # Construct font colors
    fontcolor = ((0, 255), (0, 255), (0, 255))
    # Drawing 4 words
    (((10, 30), ((0, 10))), string[0], font=font, fill=fontcolor)
    (((90, 130), ((0, 10))), string[1], font=font, fill=fontcolor)
    (((180, 230), ((0, 10))), string[2], font=font, fill=fontcolor)
    (((270, 330), ((0, 10))), string[3], font=font, fill=fontcolor)

    # Call the point() function of the brush to draw the noise.
    for i in range(0, 10000):
        xy = ((0, width), (0, height))
        fill = ((0, 255), (0, 255), (0, 255))
        (xy, fill=fill)

    # Release the brush
    del draw
    ()

# Calling functions
gen_verify_img(string)

The string variable in the original code is now outside of the function, making it a parameter to be passed into the function.

Then use a for loop to randomly select 4 characters.

string = ''
#4 randomly selected values as captcha codes
rand_str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
for i in range(0, 4):
    string += rand_str[(0, len(rand_str))]

The code runs again:

Is the code DZNO or DZN0?

6. Captcha saved locally (optional)

A large number of CAPTCHA images are required for the login operation in web development, and for training the neural operations for CAPTCHA recognition.

So there is a need to take a large number of CAPTCHA image files and we will save the bulk CAPTCHA locally.

Full Code:

import random
from PIL import Image, ImageDraw, ImageFont


def gen_verify_img(text):
    bg_color = ((20, 120), (20, 120), (150, 255))
    width = 400
    height = 100

    im = ('RGB',(width,height),bg_color)
    # Create a brush object
    draw = (im)

    # Construct the font object
    font = ('./', 100)
    # font = ImageFont.load_default().font
    # Construct font colors
    fontcolor = ((0, 255), (0, 255), (0, 255))
    # Drawing 4 words
    (((10, 30), ((0, 10))), string[0], font=font, fill=fontcolor)
    (((90, 130), ((0, 10))), string[1], font=font, fill=fontcolor)
    (((180, 230), ((0, 10))), string[2], font=font, fill=fontcolor)
    (((270, 330), ((0, 10))), string[3], font=font, fill=fontcolor)

    # Call the point() function of the brush to draw the noise.
    for i in range(0, 10000):
        xy = ((0, width), (0, height))
        fill = ((0, 255), (0, 255), (0, 255))
        (xy, fill=fill)

    # Release the brush
    del draw
    # ()
    (f'./{text}.png','png')


for i in range(100):
    string = ''
    #4 randomly selected values as captcha codes
    rand_str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    for i in range(0, 4):
        string += rand_str[(0, len(rand_str))]
    gen_verify_img(string)
    print(f'{string} CAPTCHA Generated Successfully!!')

Run it again at the end:

Partial CAPTCHA display:

Note: If you then deform or rewrite the code in this article, you may get a more varied CAPTCHA, how to play depends on the screen money you.

Above is the use of Python to generate random CAPTCHA details, more information about Python CAPTCHA please pay attention to my other related articles!