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()
标签:distance,截图,img,滑块,self,ele,captcha,page,dp From: https://www.cnblogs.com/yoyo1216/p/18576687