如下代码,遇到滑块验证码之前运行正常,程序也计算出了正确的缺口距离,但到了拖动滑块的时候:
滑块不是拖动过头,就是拖动的不够。经过反复尝试,我发现原因是:
底部滑块和上面图片的滑动速度不一致,每次滑动,速度比都会变。比如滑块滑动10个像素,上方的图形有可能滑动5个像素,也有可能滑动15个像素。
另外,如果加上滑块的while循环,反复移动滑块,也会报错。
我再次追加赏金,主要解决几个问题:
1、滑块和图形速度比不一样
(请注意,我写的计算两个图形距离的函数,并不能计算出滑块的绝对坐标,那只是滑块相对于背景图的相对坐标)
2、循环拖动滑块验证码报错
3、最终,是希望程序可以自动循环移动滑块,并成功验证。
悬赏求正确的解决代码(请直接在我的代码上面修改),首位正确答案的朋友,只要我运行通过滑块验证码,马上结算,言出必行,我的信用杠杠的。另外,如果有朋友对程序提出一些更好的改法,我也会额外打赏。
加上滑块的while循环,移动滑块报错如下
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\PyCharm 2021.1.3\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "C:\PyCharm 2021.1.3\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/PycharmProjects/pythonProject2/test7.py", line 80, in <module>
tab.ele('xpath://*[@id="dx_captcha_basic_bg_1"]/canvas', timeout=2).get_screenshot(name='ping_an.png')
File "C:\PycharmProjects\pythonProject2\venv\lib\site-packages\DrissionPage\_elements\chromium_element.py", line 537, in get_screenshot
left, top = self.rect.location
File "C:\PycharmProjects\pythonProject2\venv\lib\site-packages\DrissionPage\_units\rect.py", line 35, in location
return self._get_page_coord(*self.viewport_location)
File "C:\PycharmProjects\pythonProject2\venv\lib\site-packages\DrissionPage\_units\rect.py", line 47, in viewport_location
m = self._get_viewport_rect('border')
File "C:\PycharmProjects\pythonProject2\venv\lib\site-packages\DrissionPage\_units\rect.py", line 100, in _get_viewport_rect
return self._ele.owner._run_cdp('DOM.getBoxModel', backendNodeId=self._ele._backend_id)['model'][quad]
File "C:\PycharmProjects\pythonProject2\venv\lib\site-packages\DrissionPage\_pages\chromium_base.py", line 383, in _run_cdp
return r if __ERROR__ not in r else raise_error(r, self.browser, ignore)
File "C:\PycharmProjects\pythonProject2\venv\lib\site-packages\DrissionPage\_functions\tools.py", line 202, in raise_error
raise r
DrissionPage.errors.NoRectError: 该元素没有位置及大小。
import cv2
import time
import random
from DrissionPage import Chromium, ChromiumOptions
def find_slider_and_gap(image_path):
# 函数功能:opencv计算滑块和缺口图片的距离,坐标
# 读取图片
image = cv2.imread(image_path)
if image is None:
raise ValueError("Image not found or unable to read")
# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 使用高斯模糊减少噪声
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 使用Canny边缘检测
edges = cv2.Canny(blurred, 50, 150)
# 使用轮廓检测找到滑块和缺口
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 找到最大的两个轮廓(假设滑块和缺口是最明显的两个轮廓)
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:2]
if len(contours) < 2:
raise ValueError("Not enough contours found")
# 计算轮廓的边界框
slider_box = cv2.boundingRect(contours[0])
gap_box = cv2.boundingRect(contours[1])
# 计算滑块和缺口的中心点
slider_center = (slider_box[0] + slider_box[2] // 2, slider_box[1] + slider_box[3] // 2)
gap_center = (gap_box[0] + gap_box[2] // 2, gap_box[1] + gap_box[3] // 2)
# 计算滑块和缺口在X轴上的距离
distance_x = abs(slider_center[0] - gap_center[0])
# 绘制边界框和中心点
cv2.rectangle(image, slider_box, (0, 255, 0), 2)
cv2.rectangle(image, gap_box, (0, 0, 255), 2)
cv2.circle(image, slider_center, 5, (0, 255, 0), -1)
cv2.circle(image, gap_center, 5, (0, 0, 255), -1)
# # 显示结果图像
# cv2.imshow('Result', image)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
# "滑块中心坐标: {slider_center}"
# "缺口中心坐标: {gap_center}"
# "滑块和缺口在X轴上的距离: {distance_x}"
return slider_center, gap_center, distance_x
co = ChromiumOptions()
co.incognito() # 无痕模式
browser = Chromium(co)
tab = browser.get_tab()
page = tab.get('https://auth.orangebank.com.cn/cimp-ccs-pc/#/p/ebank-login')
# 输入用户名
ele = tab.ele('#ADM')
ele.input("2000878439@03")
time.sleep(0.5)
print("此处先手工输入密码,任意键后5秒,继续", input())
time.sleep(5)
tab.ele('xpath://*[@id="app"]/div/div[2]/div[3]/div[1]/div[2]/div[2]/form/div[3]/div/div/span/button').click()
# 对当前元素截图,背景图
tab.wait.ele_displayed('xpath://*[@id="dx_captcha_basic_bg_1"]/canvas')
tab.ele('xpath://*[@id="dx_captcha_basic_bg_1"]/canvas', timeout=2).get_screenshot(name='ping_an.png')
# 示例使用
image_path = 'ping_an.png'
slider_center, gap_center, distance_x = find_slider_and_gap(image_path)
print(f"滑块中心坐标: {slider_center}")
print(f"缺口中心坐标: {gap_center}")
print(f"滑块和缺口在X轴上的距离: {distance_x}")
k = 0
while k < 5:
slider = tab.ele('xpath://*[@id="dx_captcha_basic_slider-img-normal_1"]')
slider.wait.clickable() # 确保元素加载完成且可点击
# # 使用动作链进行拖动操作
tab.actions.move_to(slider, duration=0.5).hold().move(distance_x, random.uniform(-5, 5), duration=1).release()
k= k+1
print(f"第{k}次")
time.sleep(1)
print("程序结束")