关于滑块验证码的问题

news2024/12/23 5:20:28

这里写自定义目录标题

    • 一、超级鹰
    • 二、图片验证模拟登录
      • 1、页面分析
        • 1.1、模拟用户正常登录流程
        • 1.2、识别图片里面的文字
      • 2、代码实现
    • 三、滑块模拟登录
      • 1、页面分析
      • 2、代码实现(通过对比像素获取缺口位置)
    • 四、openCV
      • 1、简介
      • 2、代码
      • 3、案例
    • 五、selenium 反爬
    • 六、百度智能云 —— EasyDL
      • 1、简介
      • 2、使用步骤

一、超级鹰

是一个智能图片验证码识别、图片分类平台。

工具网址:https://www.chaojiying.com/

步骤:

1、注册账号密码进行登录;

2、进入登录界面之后,点击软件 ID,生成一个软件 ID;

在这里插入图片描述

3、填入对应的软件名称和软件说明,软件 KEY 不用改,最后点击提交按钮;

在这里插入图片描述

4、点击”开发文档“选项,选择“超级鹰图像识别 Python 语言 Demo 下载”选项,将对应代码的压缩包下载下来,解压;

在这里插入图片描述

5、解压后的文件里,找到.py文件,通过 pycharm 打开后,按提示修改以下代码。

if __name__ == '__main__':
    #用户中心>>软件ID 生成一个替换 96001
    chaojiying = Chaojiying_Client('超级鹰用户名', '超级鹰用户名的密码', '96001')
    #本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    im = open('a.jpg', 'rb').read()
    #1902 验证码类型  官方网站>>价格体系 3.4+版 print 后要加()
    print(chaojiying.PostPic(im, 1902))
    #print chaojiying.PostPic(base64_str, 1902)  #此处为传入 base64代码

二、图片验证模拟登录

目标网站:https://www.bilibili.com/

需求:模拟登录

1、页面分析

采用 selenium 技术进行模拟登录

1.1、模拟用户正常登录流程
  • 在网站首页点击登录按钮;
  • 弹出框输入账号和密码,点击登录按钮;
  • 出现验证码图片识别。
1.2、识别图片里面的文字
  • 获取要识别的文字(通过 selenium 的截图功能,先截全屏,然后将验证码图片抠出来);
  • 使用超级鹰识别验证码图片文字,获取文字的坐标;
  • 根据文字坐标进行点击;
  • 点击完成,最后点击确认按钮。

2、代码实现

import time # 导入 time 模块,用于时间相关操作
from PIL import Image # 导入 Image 模块,用于图像处理
from selenium import webdriver # 导入 webdriver 模块,用于自动化测试和控制浏览器
from selenium.webdriver import ActionChains # 导入 ActionChains 类,用于模拟用户操作
from selenium.webdriver.common.by import By # 导入 By 类,用于定位元素
from selenium.webdriver.support.wait import WebDriverWait # 导入 WebDriverWait 类,用于等待元素加载
from selenium.webdriver.support import expected_conditions as EC # 导入 EC 模块,用于预期条件判断
from chaojiying_Python.chaojiying import Chaojiying_Client # 引入超级鹰验证码识别 API 客户端

class Bili_login(object):
    # 初始法方法,用户名跟密码
    def __init__(self, username, password):
        # 加载驱动
        self.driver = webdriver.Chrome()
        # 窗口最大化
        self.driver.maximize_window()
        # 目标 url
        self.url = 'https://www.bilibili.com/'
        # 用户名
        self.username = username
        # 密码
        self.password = password
        # 显示等待,判断驱动是否加载出来
        self.wait = WebDriverWait(self.driver, 100)

    # 加载得到验证码图片
    def get_img(self):
        # 加载网站
        self.driver.get(self.url)
        # 等待2秒
        time.sleep(2)
        # 点击登录
        self.driver.find_element(By.CLASS_NAME, 'header-login-entry').click()
        # 显示等待,判断账号与密码输入框是否加载出来
        self.wait.until(
            EC.presence_of_element_located((By.CLASS_NAME, 'login-pwd-wp')) # 注意方法里面要填元组
        )
        # 输入账号
        self.driver.find_element(By.XPATH, '//form[@class="tab__form"]/div[1]/input').send_keys(self.username)
        # 等待0.5秒
        time.sleep(0.5)
        # 输入密码
        self.driver.find_element(By.XPATH, '//form[@class="tab__form"]/div[3]/input').send_keys(self.username)
        # 点击登录
        self.driver.find_element(By.CLASS_NAME, 'btn_primary ').click()
        # 判断验证码元素是否加载出来
        self.wait.until(
            EC.presence_of_element_located((By.CLASS_NAME, 'geetest_item_img'))
        )
        # 保存验证码图片
        div_img = self.save_img()
        # 返回验证码图片
        return div_img

    # 下载验证码图片到本地
    def save_img(self):
        # 等待2秒
        time.sleep(2)
        # 截全屏图片
        self.driver.save_screenshot('images/back_img.png')
        # 获取验证码图片的元素
        div_img = self.driver.find_element(By.CLASS_NAME, 'geetest_panel_next')
        # 获取左上角的坐标,返回 x,y 的坐标
        location = div_img.location
        # 获取宽度和高度
        size = div_img.size
        # 获取左上角的坐标
        x1, y1 = int(location['x']), int(location['y'])
        # 获取右下角的坐标
        x2, y2 = x1 + size['width'], y1 + size['height']
        # 加载背景图
        back_img = Image.open('images/back_img.png')
        # 截图,截图建议电脑缩放比例为100%
        img = back_img.crop((x1, y1, x2, y2))
        # 保存图片
        img.save('images/验证码图片.png')
        # 返回验证码图片的元素
        return div_img

    # 点击文字做验证
    def click_font(self, loc_dic, div_img):
        # 循环依次点击
        for x, y in loc_dic.items():
            # 鼠标行为链
            action = ActionChains(self.driver)
            # 鼠标移动点击
            action.move_to_element_with_offset(div_img, int(x), int(y)).click().perform()
        # 等待1秒
        time.sleep(1)
        # 点击确定
        self.driver.find_element(By.CLASS_NAME, 'geetest_commit_tip').click()

    # 主逻辑处理
    def main(self):
        # 加载得到验证码图片
        div_img = self.get_img()
        # 用超级鹰识别位置
        chaojiying = Chaojiying_Client('替换超级鹰用户名', '替换超级鹰用户名的密码', '949117')
        # 本地图片文件路径
        im = open('images/验证码图片.png', 'rb').read()
        # 验证码类型
        log_list = chaojiying.PostPic(im, 9004)['pic_str'].split('|')
        # 处理坐标数据
        loc_dic = {i.split(',')[0]: i.split(',')[1] for i in log_list}
        # 打印位置坐标
        # print(loc_dic)
        # 点击图片内文字
        self.click_font(loc_dic, div_img)

# 主程序
if __name__ == '__main__':
    # 创建了一个对象
    b = Bili_login('123456', '123456')
    # 调用 main 方法
    b.main()

三、滑块模拟登录

目标网站:https://www.geetest.com/demo/slide-float.html

需求:模拟登录

1、页面分析

点击“点击按钮进行验证",会出现滑块。

滑块验证一般使用 selenium 实现,需要先确定滑动的距离。

获取缺口位置(三种方法)

  • 通过对比像素获取缺口位置
  • 通过 openCV 的方式,得到缺口位置
  • 百度智能云(机器学习)识别缺口位置

使用 selenium 进行滑动。

2、代码实现(通过对比像素获取缺口位置)

将图片保存下来,通过像素识别,需要获取两张图片。一张背景图片(有缺口),一张完整图片。对比像素,拿到缺口位置的坐标,使用 selenium 进行滑动。

import random  # 导入 random 模块,用于生成随机数
import time  # 导入 time 模块,用于时间相关操作
import pyautogui  # 导入 pyautogui 模块,用于控制鼠标和键盘
from PIL import Image  # 导入 Image 模块,用于图像处理
from selenium.webdriver.support.wait import WebDriverWait  # 导入 WebDriverWait 类,用于等待元素加载
from selenium import webdriver  # 导入 webdriver 模块,用于自动化测试和控制浏览器
from selenium.webdriver.support import expected_conditions as EC  # 导入 EC 模块,用于预期条件判断
from selenium.webdriver.common.by import By  # 导入 By 类,用于定位元素

class FloatSlide(object):
    # 初始化方法
    def __init__(self):
        # 确定 url
        self.url = 'https://www.geetest.com/demo/slide-float.html'
        # 加载驱动
        self.driver = webdriver.Chrome()
        # 最大化窗口
        self.driver.maximize_window()
        # 显示等待
        self.wait = WebDriverWait(self.driver, 100)
        # 缺口图片保存位置
        self.gap_img = 'images/gap.png'
        # 完整图片保存位置
        self.intact_img = 'images/intact.png'

    # 加载图片并截取图片
    def load_img(self):
        # 加载网站
        self.driver.get(self.url)
        # 等待2秒
        time.sleep(2)
        # 点击按钮
        self.driver.find_element(By.CLASS_NAME, 'geetest_radar_tip').click()
        # 用显示判断,图片是否加载出来
        self.wait.until(
            EC.presence_of_element_located((By.XPATH, '//div[@class="geetest_slicebg geetest_absolute"]'))
        )
        # 修改样式,获取缺口图片
        self.driver.execute_script('document.querySelectorAll("canvas")[1].style="opacity: 1; display: none;"')
        # 找到验证码图片的标签元素
        div_img = self.driver.find_element(By.CLASS_NAME, 'geetest_window')
        # 等待1秒
        time.sleep(1)
        # 缺口图片的保存位置
        div_img.screenshot(self.gap_img)
        # 修改样式,获取完整图片
        self.driver.execute_script('document.querySelectorAll("canvas")[2].style=""')
        # 完整图片的保存位置
        div_img.screenshot(self.intact_img)
        # 恢复样式
        self.driver.execute_script('document.querySelectorAll("canvas")[1].style="opacity: 1; display: block;"')

    # 对比验证图片,获取缺口位置
    def get_gap(self):
        # 加载缺口图片
        gap_img = Image.open(self.gap_img)
        # 加载完整图片
        intact_img = Image.open(self.intact_img)
        # 从第一个位置开始做对比
        left = 0
        # 嵌套循环做对比
        for x in range(0, gap_img.size[0]):
            for y in range(0, gap_img.size[1]):
                # 判断像素
                if not self.is_pixel_equal(gap_img, intact_img, x, y):
                    # 相同赋值给 left
                    left = x
                    # 不相同,返回 x 坐标
                    return left

    # 判断像素
    def is_pixel_equal(self, gap_img, intact_img, x, y):
        # 加载缺口图片位置
        pixel1 = gap_img.load()[x, y]
        # 加载完整图片位置
        pixel2 = intact_img.load()[x, y]
        # 打印图片位置
        # print(pixel1, pixel2)
        # 阈值
        threshold = 60
        # 对比 RGB
        if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(pixel1[2] - pixel2[2]) < threshold:
            # 在阈值内相似返回 True
            return True
        # 不在阈值内不相似返回 False,缺口找到
        return False

    # 滑动滑块
    def move_slide(self, offset_x, offset_y, left):
        # pip install pyautogui 导入 pyautogui 模块,用于控制鼠标和键盘
        # 将鼠标移动到指定位置 (offset_x, offset_y)
        pyautogui.moveTo(offset_x, offset_y, duration=0.1 + random.uniform(0, 0.1 + random.randint(1, 100) / 100))
        # 按下鼠标,准备开始滑动
        pyautogui.mouseDown()
        # 在当前 offset_y 的基础上增加一个随机值
        offset_y += random.randint(9, 19)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(15, 25) / 20), offset_y, duration=0.28)
        # 在当前 offset_y 的基础上减少一个随机值
        offset_y += random.randint(-9, 0)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(17, 23) / 20), offset_y,duration=random.randint(20, 31) / 100)
        # 在当前 offset_y 的基础上增加一个随机值
        offset_y += random.randint(0, 8)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(19, 21) / 20), offset_y,duration=random.randint(20, 40) / 100)
        # 在当前 offset_y 的基础上增加或减少一个随机值
        offset_y += random.randint(-3, 3)
        # 将鼠标移动到偏移位置 (left + offset_x + 随机值, offset_y)
        pyautogui.moveTo(left + offset_x + random.randint(-3, 3), offset_y,duration=0.5 + random.randint(-10, 10) / 100)
        # 在当前 offset_y 的基础上增加或减少一个随机值
        offset_y += random.randint(-2, 2)
        # 将鼠标移动到偏移位置 (left + offset_x + 随机值, offset_y)
        pyautogui.moveTo(left + offset_x + random.randint(-2, 2), offset_y, duration=0.5 + random.randint(-3, 3) / 100)
        # 松开鼠标左键,结束滑动操作
        pyautogui.mouseUp()
        # 等待3秒
        time.sleep(3)

    # 主函数
    def main(self):
        # 加载图片并截取图片
        self.load_img()
        # 对比验证图片,获取缺口位置
        left = self.get_gap()
        # 误差值
        left -= 6
        # 根据位置滑动滑块(测量一下浏览器左上角到滑块按钮的距离)
        x = 1260
        y = 490
        # 滑动滑块
        self.move_slide(x, y, left)

# 主程序
if __name__ == '__main__':
    # 创建了一个对象
    f = FloatSlide()
    # 调用 main 方法
    f.main()

四、openCV

1、简介

OpenCV(Open Source Computer Vision)是一个开源的计算机视觉库,它提供了丰富的图像和视频处理函数,可用于开发计算机视觉相关的应用程序。

2、代码

识别缺口位置,获取缺口距离。

# pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
import cv2

def identify_gap(bg_image, tp_image, out="images/new_image.png"):
    """
    通过cv2计算缺口位置
    :param bg_image: 有缺口的背景图片文件
    :param tp_image: 缺口小图文件图片文件
    :param out: 绘制缺口边框之后的图片
    :return: 返回缺口位置
    """
    # 读取背景图片和缺口图片
    bg_img = cv2.imread(bg_image)  # 背景图片
    tp_img = cv2.imread(tp_image)  # 缺口图片
    # 识别图片边缘
    # 因为验证码图片里面的目标缺口通常是有比较明显的边缘 所以可以借助边缘检测算法结合调整阈值来识别缺口
    # 目前应用比较广泛的边缘检测算法是Canny John F.Canny在1986年所开发的一个多级边缘检测算法 效果挺好的
    bg_edge = cv2.Canny(bg_img, 100, 200)
    tp_edge = cv2.Canny(tp_img, 100, 200)
    print(bg_edge, tp_edge)
    # 转换图片格式
    # 得到了图片边缘的灰度图,进一步将其图片格式转为RGB格式
    bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
    tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)

    # 缺口匹配
    # 一幅图像中找与另一幅图像最匹配(相似)部分 算法:cv2.TM_CCOEFF_NORMED
    # 在背景图片中搜索对应的缺口
    res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
    # res为每个位置的匹配结果,代表了匹配的概率,选出其中「概率最高」的点,即为缺口匹配的位置
    # 从中获取min_val,max_val,min_loc,max_loc分别为匹配的最小值、匹配的最大值、最小值的位置、最大值的位置
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配

    # 绘制方框
    th, tw = tp_pic.shape[:2]
    tl = max_loc  # 左上角点的坐标
    br = (tl[0] + tw, tl[1] + th)  # 右下角点的坐标
    cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2)  # 绘制矩形
    cv2.imwrite(out, bg_img)  # 保存在本地

    # 返回缺口的X坐标
    return tl[0]

# 传入两张图片,返回缺口位置
left = identify_gap('images/jindong_bg.png', 'images/jingdong_gap.png')

3、案例

需求:用 selenium 进行模拟登录

目标网站:https://passport.jd.com/new/login.aspx

页面分析

  • 切换密码登录模式
  • 输入账号和密码
  • 点击登录按钮
  • 加载完滑块之后,获取滑块验证码图片
  • 识别缺口位置,获取距离,进行滑动

代码实现

1、搭建框架

import random # 导入 random 模块,用于生成随机数
import time # 导入 time 模块,用于添加时间延迟
import cv2 # 导入 OpenCV 模块,用于图像处理
import pyautogui # 导入 pyautogui 模块,用于模拟鼠标和键盘操作
from selenium.webdriver.support.wait import WebDriverWait # 导入 WebDriverWait 类,用于等待条件
from selenium import webdriver # 导入 webdriver 模块,用于控制浏览器
from selenium.webdriver.support import expected_conditions as EC # 导入 expected_conditions 模块,用于指定预期条件
from selenium.webdriver.common.by import By # 导入 By 模块,用于指定元素定位方式
from PIL import Image # 导入 Image 模块,用于图像处理
import urllib.request # 导入 urllib.request 模块,用于进行网络请求

class JinDong_Logic(object):
    # 初始化操作
    def __init__(self, username, password):
        pass

    # 获取缺口图片
    def login(self):
        pass

    # 计算缺口位置
    def identify_gap(self, bg_image, tp_image, out="images/new_image.png"):
        pass

    # 滑动函数
    def move_slide(self, offset_x, offset_y, left):
        pass

# 主程序
if __name__ == '__main__':
    # 创建对象
    l = JinDong_Logic('123', 'abcd')
    # 调用 login 方法
    l.login()

2、初始化操作

# 初始化操作
    def __init__(self, username, password):
        # 确定 url
        self.url = 'https://passport.jd.com/new/login.aspx'
        # 账号
        self.username = username
        # 密码
        self.password = password
        # 加载驱动
        self.driver = webdriver.Chrome()
        # 窗口最大化
        self.driver.maximize_window()
        # 显示等待
        self.wait = WebDriverWait(self.driver, 100)
        # 设置图片保存位置
        # 有缺口的背景图片
        self.bg_img = 'images/bg_img.png'
        # 缺口小图片
        self.gap_img = 'images/gap_img.png'

3、获取缺口图片

# 获取缺口图片
    def login(self):
        # 加载 url
        self.driver.get(self.url)
        # 等待1秒
        time.sleep(1)
        # 切换登录方式
        self.driver.find_element(By.CLASS_NAME, 'login-tab-r').click()
        # 输入账号
        self.driver.find_element(By.ID, 'loginname').send_keys(self.username)
        # 输入密码
        self.driver.find_element(By.ID, 'nloginpwd').send_keys(self.password)
        # 等待0.5秒
        time.sleep(0.5)
        # 点击登录按钮
        self.driver.find_element(By.ID, 'loginsubmit').click()
        # 显示等待判断图片是否加载出来
        self.wait.until(
            EC.presence_of_element_located((By.CLASS_NAME, 'JDJRV-slide '))
        )
        # 获取背景图片(向图片链接发请求,获取图片)
        bg_img_url = self.driver.find_element(By.XPATH, '//div[@class="JDJRV-bigimg"]/img').get_attribute('src')
        # 保存图片
        urllib.request.urlretrieve(bg_img_url, self.bg_img)
        # 获取缺口图片
        gap_img_url = self.driver.find_element(By.XPATH, '//div[@class="JDJRV-smallimg"]/img').get_attribute('src')
        # 保存图片
        urllib.request.urlretrieve(gap_img_url, self.gap_img)
        # 修改背景图片的尺寸
        im = Image.open(self.bg_img)
        # 重新设置图片尺寸
        image = im.resize((278, 108))
        # 保存图片
        image.save('images/1.png')
        # 修改缺口图片的尺寸
        im1 = Image.open(self.gap_img)
        # 重新设置图片尺寸
        image1 = im1.resize((39, 39))
        # 保存图片
        image1.save('images/2.png')
        # 获取两张图片,计算缺口位置,识别距离
        left = self.identify_gap('images/1.png', 'images/2.png')
        # 根据位置滑动滑块(测量一下浏览器左上角到滑块按钮的距离)
        x, y = 1485, 485
        # 滑动
        self.move_slide(x, y, left)

4、计算缺口位置

# 计算缺口位置
    def identify_gap(self, bg_image, tp_image, out="images/new_image.png"):
        """
            通过cv2计算缺口位置
            :param bg_image: 有缺口的背景图片文件
            :param tp_image: 缺口小图文件图片文件
            :param out: 绘制缺口边框之后的图片
            :return: 返回缺口位置
            """
        # 读取背景图片和缺口图片
        bg_img = cv2.imread(bg_image)  # 背景图片
        tp_img = cv2.imread(tp_image)  # 缺口图片
        # 识别图片边缘
        # 因为验证码图片里面的目标缺口通常是有比较明显的边缘 所以可以借助边缘检测算法结合调整阈值来识别缺口
        # 目前应用比较广泛的边缘检测算法是Canny John F.Canny在1986年所开发的一个多级边缘检测算法 效果挺好的
        bg_edge = cv2.Canny(bg_img, 100, 200)
        tp_edge = cv2.Canny(tp_img, 100, 200)
        print(bg_edge, tp_edge)
        # 转换图片格式
        # 得到了图片边缘的灰度图,进一步将其图片格式转为RGB格式
        bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
        tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)

        # 缺口匹配
        # 一幅图像中找与另一幅图像最匹配(相似)部分 算法:cv2.TM_CCOEFF_NORMED
        # 在背景图片中搜索对应的缺口
        res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
        # res为每个位置的匹配结果,代表了匹配的概率,选出其中「概率最高」的点,即为缺口匹配的位置
        # 从中获取min_val,max_val,min_loc,max_loc分别为匹配的最小值、匹配的最大值、最小值的位置、最大值的位置
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配

        # 绘制方框
        th, tw = tp_pic.shape[:2]
        tl = max_loc  # 左上角点的坐标
        br = (tl[0] + tw, tl[1] + th)  # 右下角点的坐标
        cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2)  # 绘制矩形
        cv2.imwrite(out, bg_img)  # 保存在本地

        # 返回缺口的X坐标
        return tl[0]

5、滑动函数

# 滑动函数
    def move_slide(self, offset_x, offset_y, left):
        # pip install pyautogui 导入 pyautogui 模块,用于控制鼠标和键盘
        # 将鼠标移动到指定位置 (offset_x, offset_y)
        pyautogui.moveTo(offset_x, offset_y, duration=0.1 + random.uniform(0, 0.1 + random.randint(1, 100) / 100))
        # 按下鼠标,准备开始滑动
        pyautogui.mouseDown()
        # 在当前 offset_y 的基础上增加一个随机值
        offset_y += random.randint(9, 19)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(15, 25) / 20), offset_y, duration=0.28)
        # 在当前 offset_y 的基础上减少一个随机值
        offset_y += random.randint(-9, 0)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(17, 23) / 20), offset_y,
                         duration=random.randint(20, 31) / 100)
        # 在当前 offset_y 的基础上增加一个随机值
        offset_y += random.randint(0, 8)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(19, 21) / 20), offset_y,
                         duration=random.randint(20, 40) / 100)
        # 在当前 offset_y 的基础上增加或减少一个随机值
        offset_y += random.randint(-3, 3)
        # 将鼠标移动到偏移位置 (left + offset_x + 随机值, offset_y)
        pyautogui.moveTo(left + offset_x + random.randint(-3, 3), offset_y,
                         duration=0.5 + random.randint(-10, 10) / 100)
        # 在当前 offset_y 的基础上增加或减少一个随机值
        offset_y += random.randint(-2, 2)
        # 将鼠标移动到偏移位置 (left + offset_x + 随机值, offset_y)
        pyautogui.moveTo(left + offset_x + random.randint(-2, 2), offset_y, duration=0.5 + random.randint(-3, 3) / 100)
        # 松开鼠标左键,结束滑动操作
        pyautogui.mouseUp()
        # 等待3秒
        time.sleep(3)

完整代码

import random # 导入 random 模块,用于生成随机数
import time # 导入 time 模块,用于添加时间延迟
import cv2 # 导入 OpenCV 模块,用于图像处理
import pyautogui # 导入 pyautogui 模块,用于模拟鼠标和键盘操作
from selenium.webdriver.support.wait import WebDriverWait # 导入 WebDriverWait 类,用于等待条件
from selenium import webdriver # 导入 webdriver 模块,用于控制浏览器
from selenium.webdriver.support import expected_conditions as EC # 导入 expected_conditions 模块,用于指定预期条件
from selenium.webdriver.common.by import By # 导入 By 模块,用于指定元素定位方式
from PIL import Image # 导入 Image 模块,用于图像处理
import urllib.request # 导入 urllib.request 模块,用于进行网络请求

class JinDong_Logic(object):
    # 初始化操作
    def __init__(self, username, password):
        # 确定 url
        self.url = 'https://passport.jd.com/new/login.aspx'
        # 账号
        self.username = username
        # 密码
        self.password = password
        # 加载驱动
        self.driver = webdriver.Chrome()
        # 窗口最大化
        self.driver.maximize_window()
        # 显示等待
        self.wait = WebDriverWait(self.driver, 100)
        # 设置图片保存位置
        # 有缺口的背景图片
        self.bg_img = 'images/bg_img.png'
        # 缺口小图片
        self.gap_img = 'images/gap_img.png'

    # 获取缺口图片
    def login(self):
        # 加载 url
        self.driver.get(self.url)
        # 等待1秒
        time.sleep(1)
        # 切换登录方式
        self.driver.find_element(By.CLASS_NAME, 'login-tab-r').click()
        # 输入账号
        self.driver.find_element(By.ID, 'loginname').send_keys(self.username)
        # 输入密码
        self.driver.find_element(By.ID, 'nloginpwd').send_keys(self.password)
        # 等待0.5秒
        time.sleep(0.5)
        # 点击登录按钮
        self.driver.find_element(By.ID, 'loginsubmit').click()
        # 显示等待判断图片是否加载出来
        self.wait.until(
            EC.presence_of_element_located((By.CLASS_NAME, 'JDJRV-slide '))
        )
        # 获取背景图片(向图片链接发请求,获取图片)
        bg_img_url = self.driver.find_element(By.XPATH, '//div[@class="JDJRV-bigimg"]/img').get_attribute('src')
        # 保存图片
        urllib.request.urlretrieve(bg_img_url, self.bg_img)
        # 获取缺口图片
        gap_img_url = self.driver.find_element(By.XPATH, '//div[@class="JDJRV-smallimg"]/img').get_attribute('src')
        # 保存图片
        urllib.request.urlretrieve(gap_img_url, self.gap_img)
        # 修改背景图片的尺寸
        im = Image.open(self.bg_img)
        # 重新设置图片尺寸
        image = im.resize((278, 108))
        # 保存图片
        image.save('images/1.png')
        # 修改缺口图片的尺寸
        im1 = Image.open(self.gap_img)
        # 重新设置图片尺寸
        image1 = im1.resize((39, 39))
        # 保存图片
        image1.save('images/2.png')
        # 获取两张图片,计算缺口位置,识别距离
        left = self.identify_gap('images/1.png', 'images/2.png')
        # 根据位置滑动滑块(测量一下浏览器左上角到滑块按钮的距离)
        x, y = 1485, 485
        # 滑动
        self.move_slide(x, y, left)

    # 计算缺口位置
    def identify_gap(self, bg_image, tp_image, out="images/new_image.png"):
        """
            通过cv2计算缺口位置
            :param bg_image: 有缺口的背景图片文件
            :param tp_image: 缺口小图文件图片文件
            :param out: 绘制缺口边框之后的图片
            :return: 返回缺口位置
            """
        # 读取背景图片和缺口图片
        bg_img = cv2.imread(bg_image)  # 背景图片
        tp_img = cv2.imread(tp_image)  # 缺口图片
        # 识别图片边缘
        # 因为验证码图片里面的目标缺口通常是有比较明显的边缘 所以可以借助边缘检测算法结合调整阈值来识别缺口
        # 目前应用比较广泛的边缘检测算法是Canny John F.Canny在1986年所开发的一个多级边缘检测算法 效果挺好的
        bg_edge = cv2.Canny(bg_img, 100, 200)
        tp_edge = cv2.Canny(tp_img, 100, 200)
        print(bg_edge, tp_edge)
        # 转换图片格式
        # 得到了图片边缘的灰度图,进一步将其图片格式转为RGB格式
        bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
        tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)

        # 缺口匹配
        # 一幅图像中找与另一幅图像最匹配(相似)部分 算法:cv2.TM_CCOEFF_NORMED
        # 在背景图片中搜索对应的缺口
        res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
        # res为每个位置的匹配结果,代表了匹配的概率,选出其中「概率最高」的点,即为缺口匹配的位置
        # 从中获取min_val,max_val,min_loc,max_loc分别为匹配的最小值、匹配的最大值、最小值的位置、最大值的位置
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配

        # 绘制方框
        th, tw = tp_pic.shape[:2]
        tl = max_loc  # 左上角点的坐标
        br = (tl[0] + tw, tl[1] + th)  # 右下角点的坐标
        cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2)  # 绘制矩形
        cv2.imwrite(out, bg_img)  # 保存在本地

        # 返回缺口的X坐标
        return tl[0]

    # 滑动函数
    def move_slide(self, offset_x, offset_y, left):
        # pip install pyautogui 导入 pyautogui 模块,用于控制鼠标和键盘
        # 将鼠标移动到指定位置 (offset_x, offset_y)
        pyautogui.moveTo(offset_x, offset_y, duration=0.1 + random.uniform(0, 0.1 + random.randint(1, 100) / 100))
        # 按下鼠标,准备开始滑动
        pyautogui.mouseDown()
        # 在当前 offset_y 的基础上增加一个随机值
        offset_y += random.randint(9, 19)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(15, 25) / 20), offset_y, duration=0.28)
        # 在当前 offset_y 的基础上减少一个随机值
        offset_y += random.randint(-9, 0)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(17, 23) / 20), offset_y,
                         duration=random.randint(20, 31) / 100)
        # 在当前 offset_y 的基础上增加一个随机值
        offset_y += random.randint(0, 8)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(19, 21) / 20), offset_y,
                         duration=random.randint(20, 40) / 100)
        # 在当前 offset_y 的基础上增加或减少一个随机值
        offset_y += random.randint(-3, 3)
        # 将鼠标移动到偏移位置 (left + offset_x + 随机值, offset_y)
        pyautogui.moveTo(left + offset_x + random.randint(-3, 3), offset_y,
                         duration=0.5 + random.randint(-10, 10) / 100)
        # 在当前 offset_y 的基础上增加或减少一个随机值
        offset_y += random.randint(-2, 2)
        # 将鼠标移动到偏移位置 (left + offset_x + 随机值, offset_y)
        pyautogui.moveTo(left + offset_x + random.randint(-2, 2), offset_y, duration=0.5 + random.randint(-3, 3) / 100)
        # 松开鼠标左键,结束滑动操作
        pyautogui.mouseUp()
        # 等待3秒
        time.sleep(3)

# 主程序
if __name__ == '__main__':
    # 创建对象
    l = JinDong_Logic('123', 'abcd')
    # 调用 login 方法
    l.login()

五、selenium 反爬

在这里插入图片描述

去除 selenium 标志:

1、进入 chrome 路径

2、在文件路径出输入cmd ,回车,打开终端

3、导入 ChromeOptions 类,用于配置 Chrome 浏览器选项

from selenium.webdriver.chrome.options import Options

4、加入代码

# 创建 Options 对象,用于配置浏览器选项
options = Options()
# 连接浏览器到指定的调试地址
options.add_experimental_option('debuggerAddress', '127.0.0.1:9222')
# 加载驱动
self.driver = webdriver.Chrome(options=options)

5、把谷歌浏览器全部关闭,在终端里启动命令

chrome --remote-debugging-port=9222

6、在 PyCharm 里运行代码

案例

import random # 导入 random 模块,用于生成随机数
import time # 导入 time 模块,用于添加时间延迟
import cv2 # 导入 OpenCV 模块,用于图像处理
import pyautogui # 导入 pyautogui 模块,用于模拟鼠标和键盘操作
from selenium.webdriver.chrome.options import Options # 导入 ChromeOptions 类,用于配置 Chrome 浏览器选项
from selenium.webdriver.support.wait import WebDriverWait # 导入 WebDriverWait 类,用于等待条件
from selenium import webdriver # 导入 webdriver 模块,用于控制浏览器
from selenium.webdriver.support import expected_conditions as EC # 导入 expected_conditions 模块,用于指定预期条件
from selenium.webdriver.common.by import By # 导入 By 模块,用于指定元素定位方式
from PIL import Image # 导入 Image 模块,用于图像处理
import urllib.request # 导入 urllib.request 模块,用于进行网络请求

class JinDong_Logic(object):
    # 初始化操作
    def __init__(self, username, password):
        # 确定 url
        self.url = 'https://passport.jd.com/new/login.aspx'
        # 账号
        self.username = username
        # 密码
        self.password = password
        # 创建 Options 对象,用于配置浏览器选项
        options = Options()
        # 连接浏览器到指定的调试地址
        options.add_experimental_option('debuggerAddress', '127.0.0.1:9222')
        # 加载驱动
        self.driver = webdriver.Chrome(options=options)
        # 窗口最大化
        self.driver.maximize_window()
        # 显示等待
        self.wait = WebDriverWait(self.driver, 100)
        # 设置图片保存位置
        # 有缺口的背景图片
        self.bg_img = 'images/bg_img.png'
        # 缺口小图片
        self.gap_img = 'images/gap_img.png'

    # 获取缺口图片
    def login(self):
        # 加载 url
        self.driver.get(self.url)
        # 等待1秒
        time.sleep(1)
        # 切换登录方式
        self.driver.find_element(By.CLASS_NAME, 'login-tab-r').click()
        # 输入账号
        self.driver.find_element(By.ID, 'loginname').send_keys(self.username)
        # 输入密码
        self.driver.find_element(By.ID, 'nloginpwd').send_keys(self.password)
        # 等待0.5秒
        time.sleep(0.5)
        # 点击登录按钮
        self.driver.find_element(By.ID, 'loginsubmit').click()
        # 显示等待判断图片是否加载出来
        self.wait.until(
            EC.presence_of_element_located((By.CLASS_NAME, 'JDJRV-slide '))
        )
        # 获取背景图片(向图片链接发请求,获取图片)
        bg_img_url = self.driver.find_element(By.XPATH, '//div[@class="JDJRV-bigimg"]/img').get_attribute('src')
        # 保存图片
        urllib.request.urlretrieve(bg_img_url, self.bg_img)
        # 获取缺口图片
        gap_img_url = self.driver.find_element(By.XPATH, '//div[@class="JDJRV-smallimg"]/img').get_attribute('src')
        # 保存图片
        urllib.request.urlretrieve(gap_img_url, self.gap_img)
        # 修改背景图片的尺寸
        im = Image.open(self.bg_img)
        # 重新设置图片尺寸
        image = im.resize((278, 108))
        # 保存图片
        image.save('images/1.png')
        # 修改缺口图片的尺寸
        im1 = Image.open(self.gap_img)
        # 重新设置图片尺寸
        image1 = im1.resize((39, 39))
        # 保存图片
        image1.save('images/2.png')
        # 获取两张图片,计算缺口位置,识别距离
        left = self.identify_gap('images/1.png', 'images/2.png')
        # 根据位置滑动滑块(测量一下浏览器左上角到滑块按钮的距离)
        x, y = 1485, 455
        # 滑动
        self.move_slide(x, y, left)

    # 计算缺口位置
    def identify_gap(self, bg_image, tp_image, out="images/new_image.png"):
        """
            通过cv2计算缺口位置
            :param bg_image: 有缺口的背景图片文件
            :param tp_image: 缺口小图文件图片文件
            :param out: 绘制缺口边框之后的图片
            :return: 返回缺口位置
            """
        # 读取背景图片和缺口图片
        bg_img = cv2.imread(bg_image)  # 背景图片
        tp_img = cv2.imread(tp_image)  # 缺口图片
        # 识别图片边缘
        # 因为验证码图片里面的目标缺口通常是有比较明显的边缘 所以可以借助边缘检测算法结合调整阈值来识别缺口
        # 目前应用比较广泛的边缘检测算法是Canny John F.Canny在1986年所开发的一个多级边缘检测算法 效果挺好的
        bg_edge = cv2.Canny(bg_img, 100, 200)
        tp_edge = cv2.Canny(tp_img, 100, 200)
        print(bg_edge, tp_edge)
        # 转换图片格式
        # 得到了图片边缘的灰度图,进一步将其图片格式转为RGB格式
        bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
        tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)

        # 缺口匹配
        # 一幅图像中找与另一幅图像最匹配(相似)部分 算法:cv2.TM_CCOEFF_NORMED
        # 在背景图片中搜索对应的缺口
        res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
        # res为每个位置的匹配结果,代表了匹配的概率,选出其中「概率最高」的点,即为缺口匹配的位置
        # 从中获取min_val,max_val,min_loc,max_loc分别为匹配的最小值、匹配的最大值、最小值的位置、最大值的位置
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配

        # 绘制方框
        th, tw = tp_pic.shape[:2]
        tl = max_loc  # 左上角点的坐标
        br = (tl[0] + tw, tl[1] + th)  # 右下角点的坐标
        cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2)  # 绘制矩形
        cv2.imwrite(out, bg_img)  # 保存在本地

        # 返回缺口的X坐标
        return tl[0]

    # 滑动函数
    def move_slide(self, offset_x, offset_y, left):
        # pip install pyautogui 导入 pyautogui 模块,用于控制鼠标和键盘
        # 将鼠标移动到指定位置 (offset_x, offset_y)
        pyautogui.moveTo(offset_x, offset_y, duration=0.1 + random.uniform(0, 0.1 + random.randint(1, 100) / 100))
        # 按下鼠标,准备开始滑动
        pyautogui.mouseDown()
        # 在当前 offset_y 的基础上增加一个随机值
        offset_y += random.randint(9, 19)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(15, 25) / 20), offset_y, duration=0.28)
        # 在当前 offset_y 的基础上减少一个随机值
        offset_y += random.randint(-9, 0)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(17, 23) / 20), offset_y,
                         duration=random.randint(20, 31) / 100)
        # 在当前 offset_y 的基础上增加一个随机值
        offset_y += random.randint(0, 8)
        # 将鼠标移动到偏移位置 (offset_x + int(left * 随机值), offset_y)
        pyautogui.moveTo(offset_x + int(left * random.randint(19, 21) / 20), offset_y,
                         duration=random.randint(20, 40) / 100)
        # 在当前 offset_y 的基础上增加或减少一个随机值
        offset_y += random.randint(-3, 3)
        # 将鼠标移动到偏移位置 (left + offset_x + 随机值, offset_y)
        pyautogui.moveTo(left + offset_x + random.randint(-3, 3), offset_y,
                         duration=0.5 + random.randint(-10, 10) / 100)
        # 在当前 offset_y 的基础上增加或减少一个随机值
        offset_y += random.randint(-2, 2)
        # 将鼠标移动到偏移位置 (left + offset_x + 随机值, offset_y)
        pyautogui.moveTo(left + offset_x + random.randint(-2, 2), offset_y, duration=0.5 + random.randint(-3, 3) / 100)
        # 松开鼠标左键,结束滑动操作
        pyautogui.mouseUp()
        # 等待3秒
        time.sleep(3)

# 主程序
if __name__ == '__main__':
    # 创建对象
    l = JinDong_Logic('123', 'abcd')
    # 调用 login 方法
    l.login()

六、百度智能云 —— EasyDL

1、简介

百度智能云的 EasyDL 是一个基于深度学习的图像识别和目标检测平台,它提供了简单易用的接口和工具,使开发者可以轻松构建自己的图像识别模型。

准备该网站有缺口的背景图片,做一个训练集,运用了机器学习知识。将这些训练集导入百度智能云,在此平台标注出每一张图片的缺口位置,根据图片以及标注缺口位置,就能训练出一个模型。

有了该模型,如果传入类似的图片,就可以识别缺口位置,获取缺口的距离。

2、使用步骤

2.1、打开网站 EasyDL-零门槛AI开发平台;

2.2、点击“立即使用”;

在这里插入图片描述

2.3、点击“物体检测”;

在这里插入图片描述

2.4、点击“数据总览”,点击“创建数据集”;

在这里插入图片描述

2.5、填写数据集名称后,点击“创建并导入”;

在这里插入图片描述

2.6、导入图片后,点击“确认并返回”;

在这里插入图片描述

2.7、点击“查看与标注”;

在这里插入图片描述

2.8、点击“添加标签”;

在这里插入图片描述

2.9、填入标签名称后,点击“确定”;

在这里插入图片描述

2.10、点击“标注图片”;

在这里插入图片描述

2.11、将每一张图片的缺口位置标注出来;

在这里插入图片描述

2.12、标注好之后的图片;

在这里插入图片描述

2.13、点击“我的模型”,点击“训练模型”;

在这里插入图片描述

2.14、个人信息可选“学生”,其它信息按情况填写好后,点击“完成创建”;

在这里插入图片描述

2.15、选择好要训练的数据集后,点击“下一步”;

在这里插入图片描述

2.16、训练方式选择“常规训练”,训练环境选择第一个后,点击“开始训练”;

在这里插入图片描述

2.17、等待训练完成;

在这里插入图片描述

2.18、训练完成,点击“校验”;

在这里插入图片描述

2.19、点击“启动模型校验服务”;

在这里插入图片描述

2.20、点击“点击添加图片”;

在这里插入图片描述

2.21、选择一张图片验证;

在这里插入图片描述

2.22、验证没有问题,可以点击“申请发布”;

在这里插入图片描述

2.23、填写“服务名称”和“接口地址”后,点击“提交申请”;

在这里插入图片描述

2.24、点击“服务详情”,点击“查看API文档”;

在这里插入图片描述

2.25、点击“EasyDL版控制台“;

在这里插入图片描述

2.26、登录之后,选择”公有云部署“,选择”应用列表“,点击”创建应用“;

在这里插入图片描述

2.27、填写”应用名称“,”应用归属“选择”个人“,简单填写一下”应用描述“,点击”立即创建“;

在这里插入图片描述

2.28、点击“返回应用列表”;

在这里插入图片描述

2.29、查看“API Key”,“Secret Key”值;

在这里插入图片描述

2.30、回到“接口赋权”页面,点击“物体检测API调用文档”,找到“请求代码示例”,点击“Python3”,复制代码;

在这里插入图片描述

"""
EasyDL 物体检测 调用模型公有云API Python3实现
"""

import json
import base64
import requests
"""
使用 requests 库发送请求
使用 pip(或者 pip3)检查我的 python3 环境是否安装了该库,执行命令
  pip freeze | grep requests
若返回值为空,则安装该库
  pip install requests
"""


# 目标图片的 本地文件路径,支持jpg/png/bmp格式
IMAGE_FILEPATH = "【您的测试图片地址,例如:./example.jpg】"

# 可选的请求参数
# threshold: 默认值为建议阈值,请在 我的模型-模型效果-完整评估结果-详细评估 查看建议阈值
PARAMS = {"threshold": 0.3}

# 服务详情 中的 接口地址
MODEL_API_URL = "【您的API地址】"

# 调用 API 需要 ACCESS_TOKEN。若已有 ACCESS_TOKEN 则于下方填入该字符串
# 否则,留空 ACCESS_TOKEN,于下方填入 该模型部署的 API_KEY 以及 SECRET_KEY,会自动申请并显示新 ACCESS_TOKEN
ACCESS_TOKEN = "【您的ACESS_TOKEN】"
API_KEY = "【您的API_KEY】"
SECRET_KEY = "【您的SECRET_KEY】"


print("1. 读取目标图片 '{}'".format(IMAGE_FILEPATH))
with open(IMAGE_FILEPATH, 'rb') as f:
    base64_data = base64.b64encode(f.read())
    base64_str = base64_data.decode('UTF8')
print("将 BASE64 编码后图片的字符串填入 PARAMS 的 'image' 字段")
PARAMS["image"] = base64_str


if not ACCESS_TOKEN:
    print("2. ACCESS_TOKEN 为空,调用鉴权接口获取TOKEN")
    auth_url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials"\
               "&client_id={}&client_secret={}".format(API_KEY, SECRET_KEY)
    auth_resp = requests.get(auth_url)
    auth_resp_json = auth_resp.json()
    ACCESS_TOKEN = auth_resp_json["access_token"]
    print("新 ACCESS_TOKEN: {}".format(ACCESS_TOKEN))
else:
    print("2. 使用已有 ACCESS_TOKEN")


print("3. 向模型接口 'MODEL_API_URL' 发送请求")
request_url = "{}?access_token={}".format(MODEL_API_URL, ACCESS_TOKEN)
response = requests.post(url=request_url, json=PARAMS)
response_json = response.json()
response_str = json.dumps(response_json, indent=4, ensure_ascii=False)
print("结果:\n{}".format(response_str))

2.31、将“图片地址”,“API地址”,“ACESS_TOKEN”,“API_KEY”,“SECRET_KEY“等值替换成自己的

"""
EasyDL 物体检测 调用模型公有云API Python3实现
"""

import json
import base64
import requests
"""
使用 requests 库发送请求
使用 pip(或者 pip3)检查我的 python3 环境是否安装了该库,执行命令
  pip freeze | grep requests
若返回值为空,则安装该库
  pip install requests
"""


# 目标图片的 本地文件路径,支持jpg/png/bmp格式
IMAGE_FILEPATH = "images/1.png"

# 可选的请求参数
# threshold: 默认值为建议阈值,请在 我的模型-模型效果-完整评估结果-详细评估 查看建议阈值
PARAMS = {"threshold": 0.3}

# 服务详情 中的 接口地址
MODEL_API_URL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/detection/jdyanzheng"

# 调用 API 需要 ACCESS_TOKEN。若已有 ACCESS_TOKEN 则于下方填入该字符串
# 否则,留空 ACCESS_TOKEN,于下方填入 该模型部署的 API_KEY 以及 SECRET_KEY,会自动申请并显示新 ACCESS_TOKEN
ACCESS_TOKEN = ""
API_KEY = "替换API_KEY"
SECRET_KEY = "替换SECRET_KEY"


print("1. 读取目标图片 '{}'".format(IMAGE_FILEPATH))
with open(IMAGE_FILEPATH, 'rb') as f:
    base64_data = base64.b64encode(f.read())
    base64_str = base64_data.decode('UTF8')
print("将 BASE64 编码后图片的字符串填入 PARAMS 的 'image' 字段")
PARAMS["image"] = base64_str


if not ACCESS_TOKEN:
    print("2. ACCESS_TOKEN 为空,调用鉴权接口获取TOKEN")
    auth_url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials"\
               "&client_id={}&client_secret={}".format(API_KEY, SECRET_KEY)
    auth_resp = requests.get(auth_url)
    auth_resp_json = auth_resp.json()
    ACCESS_TOKEN = auth_resp_json["access_token"]
    print("新 ACCESS_TOKEN: {}".format(ACCESS_TOKEN))
else:
    print("2. 使用已有 ACCESS_TOKEN")


print("3. 向模型接口 'MODEL_API_URL' 发送请求")
request_url = "{}?access_token={}".format(MODEL_API_URL, ACCESS_TOKEN)
response = requests.post(url=request_url, json=PARAMS)
response_json = response.json()
response_str = json.dumps(response_json, indent=4, ensure_ascii=False)
print("结果:\n{}".format(response_str))

2.32、运行之后,可显示缺口的坐标位置。

在这里插入图片描述

记录学习过程,欢迎讨论交流,尊重原创,转载请注明出处~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1063285.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue中如何进行数据库操作与数据持久化

在Vue中进行数据库操作与数据持久化 Vue.js作为一个流行的JavaScript框架&#xff0c;通常用于构建前端应用程序&#xff0c;但它本身并不提供数据库操作或数据持久化的功能。数据库操作通常由后端服务器处理&#xff0c;而Vue负责呈现和交互。然而&#xff0c;您可以使用Vue与…

P1-Python编辑器的选择和安装

1、Python编辑器的选择、安装及配置&#xff08;PyCharm、Jupyter&#xff09; PyCharm的安装&#xff1a; https://www.jetbrains.com/pycharm/PyCharm的配置&#xff1a; 1、创建新的项目 2、导入本地已有的Pytorch anaconda环境 配置环境中问题&#xff1a; https://bl…

Kitchen Racks

厨房置物架 完美&#xff01;&#xff01;&#xff01;

【车载开发系列】S19/HEX/BIN文件解析

【车载开发系列】S19/HEX/BIN文件解析 【车载开发系列】S19/HEX/BIN文件解析 【车载开发系列】S19/HEX/BIN文件解析一. 文件烧录原理二. 为什么要文件解析三. BIN格式文件1&#xff09;bin格式优点2&#xff09;bin格式缺点 四. S-record概述五. S19&#xff0c;MOT&#xff0c…

ExoPlayer架构详解与源码分析(3)——Timeline

系列文章目录 ExoPlayer架构详解与源码分析&#xff08;1&#xff09;——前言 ExoPlayer架构详解与源码分析&#xff08;2&#xff09;——Player 文章目录 系列文章目录前言Timeline单文件或者点播流媒体文件播放列表或者点播流列表有限可播的直播流无限可播的直播流有多个P…

机器学习---RBM、KL散度、DBN

1. RBM 1.1 BM BM是由Hinton和Sejnowski提出的一种随机递归神经网络&#xff0c;可以看做是一种随机生成的 Hopfield网络&#xff0c;是能够通过学习数据的固有内在表示解决困难学习问题的最早的人工神经网络之 一&#xff0c;因样本分布遵循玻尔兹曼分布而命名为BM。BM由二…

平台项目列表页实现(二)

这里写目录标题 一、顶部盒子设计1. 顶部盒子包含项目列表和添加项目、退出登录2个按钮 二、项目列表盒子设计三、添加项目盒子设计四、退出登录功能实现五、路由导航守卫实现六、展示项目信息七、bug修复1、当项目名称太长或者项目负责人太长&#xff0c;需要一行展示&#xf…

一文详解动态链表和静态链表的区别

1、引言 本文主要是对动态链表和静态链表的区别进行原理上的讲解分析&#xff0c;先通过对顺序表和动态链表概念和特点的原理性介绍&#xff0c;进而引申出静态链表的作用&#xff0c;以及其概念。通过这些原理性的概述&#xff0c;最后总结归纳出动态链表和静态链表的区别。本…

vector的介绍以及使用方式

目录 前言 1.vector的介绍 2.构造函数 3.迭代器 4.vector空间增长问题 5.vector的增删改查 6.vector迭代器失效问题 总结 前言 即我们的string之后&#xff0c;今天小编给大家要介绍一个我们stl中另外一个常用的容器vector&#xff0c;和我们的string一样我们的vector…

Vue中如何进行分布式任务调度与定时任务管理

在Vue中进行分布式任务调度与定时任务管理 分布式任务调度和定时任务管理是许多应用程序中的关键功能之一。它们用于执行周期性的、异步的、重复的任务&#xff0c;例如数据备份、邮件发送、定时报告生成等。在Vue.js应用中&#xff0c;我们可以结合后端服务实现分布式任务调度…

浏览器技巧:谷歌浏览器六个实用设置小技巧,值得收藏

目录 1、确保你的浏览器启用标准保护选项 2、使用安全DNS&#xff08;DNS over HTTPS&#xff09; 3、网站通知修改为"静态指示方式" 4、启用页面预加载提升网页加载速度 5、阻止Chrome浏览器在后台运行 6. 更改 Chrome 启动后打开方式为"上次打开的网页&…

javaWeb超市订单管理系统

一、引言 超市管理系统(smbms)作为每个计算机专业的大学生都是一个很好的练手项目&#xff0c;逻辑层次分明&#xff0c;基础功能包括用户的登录和注销&#xff0c;用户和供应商以及订单信息的增删查改的基础功能。可以帮助我们更好的加深理解三层架构的理念&#xff0c;本项目…

复习 --- QT服务器客户端

服务器&#xff1a; 头文件&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTcpServer> #include<QTcpSocket> #include<QMessageBox> #include<QDebug> #include<QList> #include<QListWidget> #in…

电脑数据恢复怎么操作?电脑数据恢复难点是什么

随着电脑在我们日常生活中的普及&#xff0c;数据的重要性不言而喻。然而&#xff0c;在某些情况下&#xff0c;我们可能会不小心删除或因其他原因导致丢失了重要的电脑数据&#xff0c;这时候就需要进行数据恢复操作。下面我们一起来了解下电脑数据恢复的操作方法&#xff0c;…

【全3D打印坦克——基于Arduino履带式机器人】

【全3D打印坦克——基于Arduino履带式机器人】 1. 概述2. 设计机器人平台3. 3D 模型和 STL 下载文件3.1 3D打印3.2 组装 3D 打印坦克 – 履带式机器人平台3.3 零件清单 4. 机器人平台电路图4.1 定制电路板设计4.2 完成 3D 打印储罐组件 5. 机器人平台编程6. 测试3D打印机器人 -…

侯捷 C++ STL标准库和泛型编程【C++学习笔记】 超详细 万字笔记总结 笔记合集

关于STL这部分&#xff0c;原课程将其分为了四部分&#xff0c;我做笔记时&#xff0c;会将其整合&#xff0c;使其更具有整体性 文章目录 1 STL概述1.1 头文件名称1.2 STL基础介绍1.3 typename 2 OOP vs. GP3 容器3.1 容器结构分类3.2 序列式容器3.2.1 array测试深度探索 3.2.…

Python3操作MongoDb7最新版创建文档及CRUD基本操作

Python3中类的高级语法及实战 Python3(基础|高级)语法实战(|多线程|多进程|线程池|进程池技术)|多线程安全问题解决方案 Python3数据科学包系列(一):数据分析实战 Python3数据科学包系列(二):数据分析实战 Python3数据科学包系列(三):数据分析实战 MongoDB 操作手册----文档…

Zookeeper经典应用场景实战(一)

文章目录 1、Zookeeper Java客户端实战1.1、 Zookeeper 原生Java客户端使用1.2、 Curator开源客户端使用 2、 Zookeeper在分布式命名服务中的实战2.1、 分布式API目录2.2、 分布式节点的命名2.3、 分布式的ID生成器 3、Zookeeper实现分布式队列3.1、 设计思路3.2、 使用Apache …

电脑桌面黑屏,但程序还可以正常运行

问题&#xff1a;桌面黑屏&#xff0c;程序可以正常运行操作 解决方法: 1.Ctrl Alt Del 2.点击 【任务管理器】-->【文件F】-->【运行新任务N】 3.输入 explorer.exe 回车

Docker 镜像的缓存特性

Author&#xff1a;rab 目录 前言一、构建缓存二、Pull 缓存总结 前言 首先我们要清楚&#xff0c;Docker 的镜像结构是分层的&#xff0c;镜像本身是只读的&#xff08;不管任何一层&#xff09;&#xff0c;当我们基于某镜像运行一个容器时&#xff0c;会有一个新的可写层被…