import time
import ddddocr
import random
from DrissionPage import ChromiumPage
import os
import shutil


class SlideCaptchaSolver:
    def __init__(self):
        self.page = ChromiumPage()

    @staticmethod
    def delete_img_folder():
        """删除img文件夹"""
        folder_name = 'img'
        # 获取当前工作目录
        current_directory = os.getcwd()
        # 构造要删除的文件夹的完整路径
        folder_path = os.path.join(current_directory, folder_name)
        try:
            # 删除文件夹及其内容
            shutil.rmtree(folder_path)
            # print(f"成功删除文件夹: {folder_path}")
        except FileNotFoundError:
            # print(f"文件夹 '{folder_path}' 不存在")
            pass
        except Exception as e:
            print(f"发生错误: {e}")

    @staticmethod
    def get_distance_by_ddddocr():
        """使用ddddocr计算缺口距离"""
        det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
        with open('./img/target.png', 'rb') as f:
            target_bytes = f.read()
        with open('./img/background.png', 'rb') as f:
            background_bytes = f.read()
        res = det.slide_match(target_bytes, background_bytes)
        x_distance = res["target"][0]
        return x_distance

    @staticmethod
    def get_tracks(distance):
        """滑块的运动轨迹"""
        value = round(random.uniform(0.55, 0.75), 2)
        v, t, sum = 0, 0.3, 0
        plus = []
        mid = distance * value
        while sum < distance:
            if sum < mid:
                a = round(random.uniform(2.5, 3.5), 1)
            else:
                a = -round(random.uniform(2.0, 3.0), 1)
            s = v * t + 0.5 * a * (t ** 2)
            v = v + a * t
            sum += s
            plus.append(round(s))

        reduce = [-6, -4, -6, -4]
        return {'plus': plus, 'reduce': reduce}

    def move_to_gap(self, slide_ele, tracks):
        """模拟滑块滑动 https://g1879.gitee.io/drissionpagedocs/ChromiumPage/actions/#-%E4%BD%BF%E7%94%A8%E5%86%85%E7%BD%AEactions%E5%B1%9E%E6%80%A7"""
        self.page.actions.hold(f"{slide_ele}")  # 此方法用于按住鼠标左键不放,按住前可先移动到元素上
        # 使鼠标相对当前位置移动若干距离
        for track in tracks['plus']:
            self.page.actions.move(
                offset_x=track,
                offset_y=round(random.uniform(1.0, 3.0), 0),
                duration=.1
            )
        time.sleep(0.5)
        self.page.actions.release(f"{slide_ele}")  # 此方法用于释放鼠标左键,释放前可先移动到元素上。

    def solve_captcha1(self):
        """嵌入式滑块"""
        self.delete_img_folder()
        self.page.get("https://castatic.fengkongcloud.cn/pr/v1.0.4/demo.html")
        self.page.ele("@text()=嵌入式(embed)").click()
        self.page.ele('@name=account').input("test")
        self.page.ele('@name=password').input("test")
        # 下载滑块和背景图,target.png 指的是滑块的图片。background.png指的是带有缺口的背景图
        self.page.ele('.shumei_captcha_loaded_img_fg').save(path="./img/", name='target.png')
        self.page.ele('.shumei_captcha_loaded_img_bg').save(path="./img/", name='background.png')
        x_distance = self.get_distance_by_ddddocr()
        # 该网址缺口的计算得除2,因为下载的图片为600 × 300 px ,而在网页上的图片大小为300 × 150 px
        x_distance = x_distance / 2
        # 计算出的轨迹
        trajectory = self.get_tracks(x_distance)
        # 进行移动
        self.move_to_gap(slide_ele=".shumei_captcha_slide_btn_icon sm-iconfont", tracks=trajectory)
        time.sleep(0.2)
        # 对验证码页面进行截图。
        captcha1 = self.page.ele('#shumei_form_captcha_wrapper')
        if captcha1:
            captcha1.get_screenshot(path="./img/captcha1.png")

    def solve_captcha2(self):
        """浮动式(float)"""
        self.delete_img_folder()
        self.page.get("https://castatic.fengkongcloud.cn/pr/v1.0.4/demo.html")
        self.page.ele("@text()=浮动式(float)").click()
        time.sleep(1)
        # 必须先输入密码再输入账号,要不然不会弹窗
        self.page.ele('@name=password').input("test")
        self.page.ele('@name=account').input("test")
        # 下载滑块和背景图,target.png 指的是滑块的图片。background.png指的是带有缺口的背景图
        self.page.ele('.shumei_captcha_loaded_img_fg').save(path="./img/", name='target.png')
        self.page.ele('.shumei_captcha_loaded_img_bg').save(path="./img/", name='background.png')
        x_distance = self.get_distance_by_ddddocr()
        # 该网址缺口的计算得除2,因为下载的图片为600 × 300 px ,而在网页上的图片大小为300 × 150 px
        x_distance = x_distance / 2
        # 计算出的轨迹
        trajectory = self.get_tracks(x_distance)
        # 进行移动
        self.move_to_gap(slide_ele=".shumei_captcha_slide_btn_icon sm-iconfont", tracks=trajectory)
        time.sleep(0.2)
        # 对验证码页面进行截图。
        captcha2 = self.page.ele('#shumei_form_captcha_wrapper')
        if captcha2:
            captcha2.get_screenshot(path="./img/captcha2.png")

    def solve_captcha3(self):
        """弹出式(popup)"""
        self.delete_img_folder()
        self.page.get("https://castatic.fengkongcloud.cn/pr/v1.0.4/demo.html")
        self.page.ele("@text()=弹出式(popup)").click()
        self.page.ele('@name=account').input("test")
        self.page.ele('@name=password').input("test")
        # 点击登录,弹出验证码
        time.sleep(1)
        self.page.ele('.shumei_login_btn').click()
        # 下载滑块和背景图,target.png 指的是滑块的图片。background.png指的是带有缺口的背景图
        self.page.ele('.shumei_captcha_loaded_img_fg').save(path="./img/", name='target.png')
        self.page.ele('.shumei_captcha_loaded_img_bg').save(path="./img/", name='background.png')
        x_distance = self.get_distance_by_ddddocr()
        # 该网址缺口的计算得除2,因为下载的图片为600 × 300 px ,而在网页上的图片大小为300 × 150 px
        x_distance = x_distance / 2
        # 计算出的轨迹
        trajectory = self.get_tracks(x_distance)
        # 进行移动
        self.move_to_gap(slide_ele=".shumei_captcha_slide_btn_icon sm-iconfont", tracks=trajectory)
        time.sleep(0.2)
        # 对验证码页面进行截图。
        captcha3 = self.page.ele('#shumei_form_captcha_wrapper')
        if captcha3:
            captcha3.get_screenshot(path="./img/captcha3.png")

    def solve_captcha4(self):
        """无图直接滑动"""
        self.delete_img_folder()
        self.page.get("https://castatic.fengkongcloud.cn/pr/v1.0.4/demo.html")
        self.page.ele("@text()=无图直接滑动").click()
        self.page.ele('@name=account').input("test")
        self.page.ele('@name=password').input("test")
        # 点击登录,弹出验证码
        self.page.ele('.shumei_login_btn').click()
        x_distance = (300 - 40)
        # 计算出的轨迹
        trajectory = self.get_tracks(x_distance)
        # 进行移动
        self.move_to_gap(slide_ele=".shumei_captcha_slide_btn_icon sm-iconfont", tracks=trajectory)
        time.sleep(0.2)
        # 对验证码页面进行截图。
        captcha4 = self.page.ele('#shumei_form_captcha_wrapper', timeout=0.5)
        if captcha4:
            captcha4.get_screenshot(path="./img/captcha4.png")

    def solve_captcha5(self):
        """使用bytes传参,不下载验证码图片"""
        self.delete_img_folder()
        self.page.get("https://castatic.fengkongcloud.cn/pr/v1.0.4/demo.html")
        self.page.ele("@text()=嵌入式(embed)").click()
        self.page.ele('@name=account').input("test")
        self.page.ele('@name=password').input("test")
        # 点击登录,弹出验证码
        self.page.ele('.shumei_login_btn').click()
        # 直接获取到验证码滑块和背景图的bytes
        target_bytes = self.page.ele('.shumei_captcha_loaded_img_fg').src()
        background_bytes = self.page.ele('.shumei_captcha_loaded_img_bg').src()

        det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
        res = det.slide_match(target_bytes, background_bytes)

        x_distance = res["target"][0] / 2
        trajectory = self.get_tracks(x_distance)
        self.move_to_gap(slide_ele=".shumei_captcha_slide_btn_icon sm-iconfont", tracks=trajectory)
        time.sleep(0.2)
        captcha5 = self.page.ele('#shumei_form_captcha_wrapper')
        if captcha5:
            captcha5.get_screenshot(path="./img/captcha5.png")


captcha_solver = SlideCaptchaSolver()
captcha_solver.solve_captcha1()
# captcha_solver.solve_captcha2()
# captcha_solver.solve_captcha3()
# captcha_solver.solve_captcha4()
# captcha_solver.solve_captcha5()