1.有一天我需要使用自动化填写表单,但是,当我保存时,碰到了滑块,只能自己手动滑动,我自己心有不甘,决定自己破解它,不破解自动验证滑块成功誓不罢休,于是我开始思考。。。
(注:大家可以自己寻找一个需要通过滑块验证的网站,此方法适用于所有的滑块验证网站)
2.思路:首先使用selenium截全屏,然后使用selenium定位图片标签获取x,y,w,h,通过宽高截屏滑块图片,同时识别滑块缺口,识别缺口后获得缺口的横向坐标,然后使用selenium拖动滑块匀速从左向右滑动到达位置,即成功,识别效果百分之80以上。
3.主要问题有两个,一是如何定位到滑块页面,二是如何识别滑块缺口并且返回横坐标x
4.如何定位到滑块页面,主要可能需要进如iframe页面,大家可以详细搜一下如何进入和退出iframe页面的方法
5.如何识别滑块缺口并且返回横坐标x,我们首先需要一个缺口的图片作为对照,之后每次获取的背景图可根据缺口进行识别,使用此识别方式识别较为准确
def identify(bg, tp, out):
# 读取背景图片和缺口图片
bg_img = cv2.imread(bg) # 背景图片
tp_img = cv2.imread(tp) # 缺口图片
# 识别图片边缘
bg_edge = cv2.Canny(bg_img, 100, 200)
tp_edge = cv2.Canny(tp_img, 100, 200)
# 转换图片格式
bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)
# 缺口匹配
res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
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) # 保存在本地
print(tl[0])
# 返回缺口的X坐标
return tl[0]
from selenium import webdriver
from selenium.webdriver import ActionChains
import time
import cv2
def identify_gap(bg, tp, out):
'''
bg: 背景图片
tp: 缺口图片
out:输出图片
'''
# 读取背景图片和缺口图片
bg_img = cv2.imread(bg) # 背景图片
tp_img = cv2.imread(tp) # 缺口图片
# 识别图片边缘
bg_edge = cv2.Canny(bg_img, 100, 200)
tp_edge = cv2.Canny(tp_img, 100, 200)
# 转换图片格式
bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)
# 缺口匹配
res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
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) # 保存在本地
print(tl[0])
# 返回缺口的X坐标
return tl[0]
# identify_gap("result1.png","result2.png","1.png")
chome_option=webdriver.ChromeOptions()
driver=webdriver.Chrome()
driver.get("https://spcjsample.gsxt.gov.cn/index.php?m=Admin&c=Sample&a=receiveOrEditSample&oper_type=receive&sample_code=XC21320115216735911")
driver.maximize_window()
driver.find_element_by_xpath('//*[@id="formReceiveSample"]/div[2]/span').click()
time.sleep(3)
source=driver.find_element_by_xpath('//*[@id="tncode_div"]/div[5]/div[1]')
print(source.location['x'])
time.sleep(2)
ActionChains(driver).click_and_hold(source).perform()
driver.save_screenshot('result.png')
im = cv2.imread('result.png')
im = im[342:495,858:1075]
cv2.imwrite('result1.png',im)
distance = identify_gap("result1.png","result2.png","1.png")+30
i = 0
while i <= distance:
ActionChains(driver).move_by_offset(2,0).perform()
i += 2
ActionChains(driver).release().perform()
time.sleep(3)
driver.quit()
from selenium import webdriver
from selenium.webdriver import ActionChains
import time
import cv2
def identify_gap(bg, tp, out):
'''
bg: 背景图片
tp: 缺口图片
out:输出图片
'''
# 读取背景图片和缺口图片
bg_img = cv2.imread(bg) # 背景图片
tp_img = cv2.imread(tp) # 缺口图片
# 识别图片边缘
bg_edge = cv2.Canny(bg_img, 100, 200)
tp_edge = cv2.Canny(tp_img, 100, 200)
# 转换图片格式
bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)
# 缺口匹配
res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
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) # 保存在本地
print(tl[0])
# 返回缺口的X坐标
return tl[0]
# identify_gap("result1.png","result2.png","1.png")
chome_option=webdriver.ChromeOptions()
driver=webdriver.Chrome()
driver.get("https://spcjsample.gsxt.gov.cn/index.php?m=Admin&c=Sample&a=receiveOrEditSample&oper_type=receive&sample_code=XC21320115216735911")
driver.maximize_window()
driver.find_element_by_xpath('//*[@id="formReceiveSample"]/div[2]/span').click()
time.sleep(3)
source=driver.find_element_by_xpath('//*[@id="tncode_div"]/div[5]/div[1]')
target=driver.find_element_by_xpath('//*[@id="tncode_div"]/canvas[2]')
time.sleep(2)
ActionChains(driver).click_and_hold(source).perform()
driver.save_screenshot('result.png')
im = cv2.imread('result.png')
# im = im[342:495,858:1075]
sp = im.shape
sz1 = sp[0]
sz2 = sp[1]
sz3 = sp[2]
im = im[(int(sz1)//2-119):(int(sz1)//2+31),(int(sz2)//2-130):(int(sz2)//2+115)]
cv2.imwrite('result1.png',im)
distance = identify_gap("result1.png","result2.png","1.png")+4
i = 0
while i <= distance:
ActionChains(driver).move_by_offset(4,0).perform()
i += 4
ActionChains(driver).release().perform()
time.sleep(3)
driver.quit()
from selenium import webdriver
from selenium.webdriver import ActionChains
import time
import cv2
def identify_gap(bg, tp, out):
'''
bg: 背景图片
tp: 缺口图片
out:输出图片
'''
# 读取背景图片和缺口图片
bg_img = cv2.imread(bg) # 背景图片
tp_img = cv2.imread(tp) # 缺口图片
# 识别图片边缘
bg_edge = cv2.Canny(bg_img, 100, 200)
tp_edge = cv2.Canny(tp_img, 100, 200)
# 转换图片格式
bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)
# 缺口匹配
res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
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) # 保存在本地
print(tl[0])
# 返回缺口的X坐标
return tl[0]
# identify_gap("result1.png","result2.png","1.png")
chome_option=webdriver.ChromeOptions()
driver=webdriver.Chrome()
driver.get("https://spcjsample.gsxt.gov.cn/index.php?m=Admin&c=Sample&a=receiveOrEditSample&oper_type=receive&sample_code=XC21320115216735911")
# driver.maximize_window()
driver.find_element_by_xpath('//*[@id="formReceiveSample"]/div[2]/span').click()
time.sleep(3)
source=driver.find_element_by_xpath('//*[@id="tncode_div"]/div[5]/div[1]')
target=driver.find_element_by_xpath('//*[@id="tncode_div"]/canvas[2]')
time.sleep(2)
k=source.location['x']
print(k)
ActionChains(driver).click_and_hold(source).perform()
driver.save_screenshot('result.png')#这里截全屏,截全屏后再保存,之后再截图
# im = cv2.imread('result.png')
# sp = im.shape
# sz1 = sp[0]
# sz2 = sp[1]
# sz3 = sp[2]
# im = im[(int(sz1)//2-119):(int(sz1)//2+31),(int(sz2)//2-130):(int(sz2)//2+115)]
# cv2.imwrite('result1.png',im)
distance = identify_gap("result.png","result2.png","1.png")-k
print(distance)
i = 0
while i <= distance:
ActionChains(driver).move_by_offset(5,0).perform()
i += 5
ActionChains(driver).release().perform()
time.sleep(3)
driver.quit()
更新问题:
1.此滑块没有ifame页面,所以很方便进入,大家的滑块验证很大可能是ifame页面,如果发现自己自动点击不了的话可能就是这个问题。
2.此方法适用于所有验证滑块的情况,因为这个方法是直接识别滑块缺口的位置,然后计算需要移动的像素距离来实现的,是可变的、能够适用所有滑块验证。
3.通过测试了99次验证只有5次没有成功,没有成功的原因在于,滑块的缺口识别错误,因为识别缺口是有识别度的,这个方法的识别度大概在百分之85以上,如果你想增加精确度,那么可以提炼识别方法,识别的更准确,则验证更成功。