• 关于滑块验证码的问题


    一、超级鹰

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

    工具网址: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代码
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    二、图片验证模拟登录

    目标网站: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()
    
    • 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
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115

    三、滑块模拟登录

    目标网站: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()
    
    • 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
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139

    四、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')
    
    • 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

    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()
    
    • 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

    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'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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)
    
    • 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

    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]
    
    • 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

    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)
    
    • 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

    完整代码

    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()
    
    • 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
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161

    五、selenium 反爬

    在这里插入图片描述

    去除 selenium 标志:

    1、进入 chrome 路径

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

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

    from selenium.webdriver.chrome.options import Options
    
    • 1

    4、加入代码

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

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

    chrome --remote-debugging-port=9222
    
    • 1

    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()
    
    • 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
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166

    六、百度智能云 —— 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))
    
    • 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

    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))
    
    • 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

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

    在这里插入图片描述

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

  • 相关阅读:
    乘用车排气系统流场的数值模拟
    sklearn实现多项式线性回归_一元/多元 【Python机器学习系列(八)】
    vueDay04——v-if else show
    蓝桥杯训练题JAVA实现 入门训练 圆的面积
    运输层(计算机网络谢希仁第八版)——学习笔记五
    C# 中的守卫语句(GuardClause)
    PG守护进程(Postmaster)——辅助进程PgStat主流程
    1000 mil = 2.54 cm , 板子导电速度约为 1.5x10^8 m/s
    谈谈Vue项目打包的方式
    【我的Python学习笔记】从基础数据类型到爬虫,后附学姐Python爬虫笔记
  • 原文地址:https://blog.csdn.net/feiyu361/article/details/133606926