python实现旋转图片验证码识别

概要

在对某网站进行访问时,有时会出现旋转图片的验证码(如下图),这会对我们的正常访问造成困扰,因此我想能不能写一个脚本来自动解决这种困扰。

image-20230501085326051

工具

步骤

前置步骤

  1. 安装selenium并使其与当前电脑的谷歌浏览器版本相匹配,这里不再赘述
  2. 准备一个验证码测试界面,这里使用百度验证码

具体步骤

1. 使用 selenium 打开图片并获取图片src

from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

test_url = 'https://wappass.baidu.com/static/captcha/tuxing.html?ak=33c48884b7df83d4230e07cbcd0d07fd&backurl=https%3A%2F%2Faiqicha.baidu.com&timestamp=1634288600&signature=02fafac36a570b03a3c9100ec68b02e5'
# 实例化一个浏览器对象
browser = Chrome()
# 访问网站
browser.get(test_url)
# 隐式等待寻找图片元素
img = WebDriverWait(browser, 3).until(
    EC.presence_of_element_located((By.CLASS_NAME, 'vcode-spin-img'))
)
# 获取图片元素的src
img_src = img.get_attribute('src')

2. 解析图片

解析图片有多种方式,这里使用api解析图片

import re
import base64
from requests import get, post
from io import BytesIO

# 将图片转化为base64格式
def get_img_base64(self, url):
    res = get(url)
    return 'data:image/jpeg;base64,' + str(base64.b64encode(BytesIO(res.content).read())).replace("b'", '').replace("'", '')

# 获取图片旋转角度
def get_operator(img_base64):
    url = 'https://www.detayun.cn/openapi/verify_code_identify/'
    data = {
        'key': 'xxxxxxxxxxxxxxxx',  # 在https://www.detayun.cn/openapi处申请key
        'verify_idf_id': '9',   # 9表示旋转图片,详情见api帮助文档
        'img_base64': img_base64,
        'words': ''     # 这里不适用
    }
    res = post(url, data=data)
    if res.status_code == 200:
        angel = re.findall('(\\d+)', res.json()['data']['res_str'])[0]
        offset = int(angel) / 360 * 211
        drag_and_drop(offset)

3. 旋转图片

# 执行图片旋转
# 下面两个定义了每次旋转的角度,使其更符合人类实际操作
def ease_out_quart(x):
    return 1 - pow(1 - x, 4)

def get_tracks(distance, seconds):
    tracks = [0]
    offsets = [0]
    for t in np.arange(0.0, seconds, 0.05):
        offset = round(ease_out_quart(t / seconds) * distance)
        tracks.append(offset - offsets[-1])
        offsets.append(offset)
    return offsets, tracks

# 旋转操作
def drag_and_drop(offset):
    # 找到需要拖动的元素
    btn = WebDriverWait(browser, 3).until(
        EC.presence_of_element_located((By.CLASS_NAME, 'vcode-spin-button'))
    )
    # 计算出每次滑动的距离
    offset, tracks = get_tracks(offset, 1.5)
    # 按住元素
    ActionChains(browser).click_and_hold(btn).perform()
    # 拖动元素
    for x in tracks:
        ActionChains(browser).move_by_offset(x, 0).perform()
    # 短暂停止后松开鼠标
    ActionChains(browser).pause(0.3).release().perform()

运行结果

bdt

知识共享许可协议
python实现旋转图片验证码识别Wantz 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
上一篇
下一篇