一个菜鸟小白的第一次
先说下背景吧,本人除了上大学时学过C++以外,再没学过任何编程,而且当年连二级都没过。最近单位要录系统,就是把excel表里的东西录到网站上。如下:
总共有两千多数据,由于分工问题,录乱了,不知道哪些录了,哪些没录。所以下定决心写个小脚本。
下面进入正题,网站的滑块验证码长这样
存放在两个canvas标签里,两张图的大小是一致的。
获取这两张图片也是费了我不少功夫,好在找到了能直接用的代码。但是现在忘了抄的谁的了,抱歉。
# 下面的js代码根据canvas文档说明而来
JS = 'return document.getElementsByTagName("canvas")[0].toDataURL("image/png");'
# 执行 JS 代码并拿到图片 base64 数据
im_info = driver.execute_script(JS) # 执行js文件得到带图片信息的图片数据
im_base64 = im_info.split(',')[1] # 拿到base64编码的图片信息
im_bytes = base64.b64decode(im_base64) # 转为bytes类型
with open('target.png', 'wb') as f: # 保存图片到本地
f.write(im_bytes)
说真的,对于一个刚开始的小白,差点就刚开始就结束,网上的教程看了一堆,有直接给出left坐标的,也有给三张图片的,也有给两张图片(一张缺口图,一张滑块图),可我偏偏遇到的是两张大小一样的。
所以一开始我用网上的模糊匹配,怎么匹配位移都是0.在挣扎了两天后终于开窍了。说下我的思路:其实挺简单的,就是先从滑块图上把小滑块截图出来,再进行模糊匹配,这样就可以得到位移了。
上代码:
tem = cv2.imread("template.png")
tem1 = cv2.GaussianBlur(tem, (3, 3), 0)
canny2 = cv2.Canny(tem1, 300, 500) # 最大和最小阈值
contours, hierarchy = cv2.findContours(canny2, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
for i, contour in enumerate(contours):
if 200 < cv2.arcLength(contour, True) < 500:
x, y, w, h = cv2.boundingRect(contour) # 确定滑块位置
cropped_image = tem[y:y + h, x:x + w] # 在滑块图上截出滑块
cv2.imwrite("save.png", cropped_image)
sleep(1)
target = cv2.imread("target.png", 0) # 读取灰度图
target = cv2.GaussianBlur(target, (3, 3), 0) # 高斯处理
canny1 = cv2.Canny(target, 200, 400, True) # 最大和最小阈值
temp = cv2.imread("save.png", 0)
temp = cv2.GaussianBlur(temp, (3, 3), 0)
canny3 = cv2.Canny(temp, 200, 450) # 最大和最小阈值
res = cv2.matchTemplate(canny1, canny3, cv2.TM_CCOEFF_NORMED) # 模糊匹配
# 最小值,最大值,并得到最小值, 最大值的索引
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
top_left = max_loc[0] # 横坐标
i, j = max_loc # 获取x,y位置坐标
w, h = temp.shape[::-1] # 宽高
print(i, j, w, h)
至此,终于把这个滑块搞定了,试了几次准确率不是很高,不知道问题出在哪,欢迎大神能够指导。最后就加了个循环,多试几次就搞定了。下一篇我再说说这次录数据遇到的坑,然后是怎么解决的。
完整代码就不上了,感觉重复太多,有需要的可以私下联系下,实在是拿不出手,哈哈哈~~~~