0%

使用背景

在自动化登录平台时,某些平台有验证码限制登录。因此开发脚本用来自动识别并提取验证码获得登录权限。

调用库

1
2
3
4
5
6
7
8
9
10
11
12
13
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager # 如果想要自动下载 driver 可以用这个
from selenium.webdriver.common.by import By
import requests
from PIL import Image, ImageFilter
from PIL import ImageEnhance
import pytesseract
import base64
from io import BytesIO
import cv2
import numpy as np

抓取图像函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
def get_image():
# 使用 Service 对象来指定 chromedriver 路径
service = Service(executable_path='D:\chromedriver-win64\chromedriver.exe') # 指定你下载的 chromedriver 路径
driver = webdriver.Chrome(service=service)

# 或者使用 webdriver_manager 自动管理 chromedriver(无需手动下载)
# driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

# 打开网页
driver.get('http://119.3.185.162:8085/login')
time.sleep(2)
# 关闭浏览器
# driver.quit()
# 定位验证码的图像元素
captcha_element = driver.find_element(By.ID, 'verifyCode') # 根据实际的 XPath 修改

# 获取验证码图像的 URL
captcha_url = captcha_element.get_attribute('src')

# 确保获取的是 blob URL
if captcha_url.startswith('blob:'):
print("获取到的 Blob URL:", captcha_url)

# 使用 JavaScript 提取 blob 数据并转换为 Base64
captcha_base64 = driver.execute_script("""
var img = document.getElementById('verifyCode');
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
return canvas.toDataURL('image/png').substring(22); // 去掉前缀部分
""")

# 解码 Base64 数据
captcha_data = base64.b64decode(captcha_base64)
save_path = "E:\script\Tools\image\captcha_image.png"
# 将解码后的数据保存为图像文件
with open(save_path, "wb") as f:
f.write(captcha_data)

image = Image.open(save_path)

image = image.convert('L') # 转换为灰度图

threshold = 200 # 可以根据图像的亮度调整此值
image = image.point(lambda p: p > threshold and 255) # 二值化

# image = image.filter(ImageFilter.MedianFilter()) # 中值滤波

enhancer = ImageEnhance.Contrast(image)
image = enhancer.enhance(0.8) # 调整对比度,数字越大对比度越强

# image = image.resize((image.width * 2, image.height * 2)) # 将图像放大两倍
image.show()

pytesseract.pytesseract.tesseract_cmd = r"D:\Program\ocr\tesseract.exe"

# 只识别数字(适用于验证码)
custom_config = r'--oem 3 --psm 6 -c tessedit_char_whitelist=0123456789'
captcha_text = pytesseract.image_to_string(image, config=custom_config)

# 输出识别到的文本
print("识别到的文本是:", captcha_text)

验证码识别函数

该函数目前仅支持无干扰图像识别。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def cvverification_code():
# 1. 读取图像并转换为灰度图像
image = cv2.imread("E:\script\Tools\image\captcha_image.png", cv2.IMREAD_GRAYSCALE)

# 2. 图像二值化处理
# 二值化处理(反转颜色使得背景为白色,文字为黑色)
_, thresh = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY_INV)

# 3. 使用开操作去除干扰线(去除小的噪点)
kernel = np.ones((3, 3), np.uint8) # 定义形态学操作的内核
opened_image = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

# 4. 使用闭操作填补空隙,去除竖线和横线
closed_image = cv2.morphologyEx(opened_image, cv2.MORPH_CLOSE, kernel)

# 5. 可选:应用中值滤波去除噪点
filtered_image = cv2.medianBlur(closed_image, 3)

# 6. 显示处理后的图像
cv2.imshow('Filtered Image', filtered_image)
# cv2.waitKey(0)
# cv2.destroyAllWindows()

# 7. 如果需要保存处理后的图像
cv2.imwrite('filtered_captcha.png', filtered_image)

# 8. 将处理后的图像转换为 PIL 格式
pil_image = Image.fromarray(filtered_image)

# 9. 使用 pytesseract 识别图像中的文本
custom_config = r'--psm 6' # 页面分割模式(PSM 6 适用于单行文本)
pytesseract.pytesseract.tesseract_cmd = r"D:\Program\ocr\tesseract.exe"
captcha_text = pytesseract.image_to_string(pil_image, config=custom_config)

# 10. 输出识别的文本
print("识别的文本:", captcha_text)

主函数

1
get_image()