• 售前

  • 售后

热门帖子
入门百科

python 模仿网站登录——滑块验证码的识别

[复制链接]
AriesHun 显示全部楼层 发表于 2021-10-26 12:23:27 |阅读模式 打印 上一主题 下一主题
平凡滑动验证


以http://admin.emaotai.cn/login.aspx为例这类验证码只需要我们将滑块拖动指定位置,处置惩罚起来比力简单。拖动之前需要先将滚动条滚动到指定元素位置。
  1. import time
  2. from selenium import webdriver
  3. from selenium.webdriver import ActionChains
  4. # 新建selenium浏览器对象,后面是geckodriver.exe下载后本地路径
  5. browser = webdriver.Firefox()
  6. # 网站登陆页面
  7. url = 'http://admin.emaotai.cn/login.aspx'
  8. # 浏览器访问登录页面
  9. browser.get(url)
  10. browser.maximize_window()
  11. browser.implicitly_wait(5)
  12. draggable = browser.find_element_by_id('nc_1_n1z')
  13. # 滚动指定元素位置
  14. browser.execute_script("arguments[0].scrollIntoView();", draggable)
  15. time.sleep(2)
  16. ActionChains(browser).click_and_hold(draggable).perform()
  17. # 拖动
  18. ActionChains(browser).move_by_offset(xoffset=247, yoffset=0).perform()
  19. ActionChains(browser).release().perform()
复制代码

拼图滑动验证


我们以欧模网许多网站利用的都是类似的方式。由于验证码及拼图都有显着豁亮的界限,图片辨识度比力高。以是我们实验先用cv2的边缘检测辨认出界限,然后举行含糊匹配,匹配出拼图在验证码图片的位置。

边缘检测


cv2模块提供了多种边缘检测算子,包罗Sobel、Scharr、Laplacian、prewitt、Canny或Marr—Hildreth等,每种算子得出的结果差别。这里我们用Canny算子,测试了许多算子,这种结果最好。

我们通过一个步伐调整一下canny算子的阈值,使得输出图片只包罗拼图表面。
  1. import cv2
  2. lowThreshold = 0
  3. maxThreshold = 100
  4. # 最小阈值范围 0 ~ 500
  5. # 最大阈值范围 100 ~ 1000
  6. def canny_low_threshold(intial):
  7.   blur = cv2.GaussianBlur(img, (3, 3), 0)
  8.   canny = cv2.Canny(blur, intial, maxThreshold)
  9.   cv2.imshow('canny', canny)
  10. def canny_max_threshold(intial):
  11.   blur = cv2.GaussianBlur(img, (3, 3), 0)
  12.   canny = cv2.Canny(blur, lowThreshold, intial)
  13.   cv2.imshow('canny', canny)
  14. # 参数0以灰度方式读取
  15. img = cv2.imread('vcode.png', 0)
  16. cv2.namedWindow('canny', cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
  17. cv2.createTrackbar('Min threshold', 'canny', lowThreshold, max_lowThreshold, canny_low_threshold)
  18. cv2.createTrackbar('Max threshold', 'canny', maxThreshold, max_maxThreshold, canny_max_threshold)
  19. canny_low_threshold(0)
  20. # esc键退出
  21. if cv2.waitKey(0) == 27:
  22.   cv2.destroyAllWindows()
复制代码
测试了多少个图片发现最小阈值100、最大阈值500输出结果比力抱负。

拼图匹配


我们用cv2的matchTemplate方法举行含糊匹配,匹配方法用CV_TM_CCOEFF_NORMED归一化干系系数匹配。
几种方法算法详见。
【1】 平方差匹配 method=CV_TM_SQDIFF square dirrerence(error)
这类方法利用平方差来举行匹配,最好匹配为0.匹配越差,匹配值越大.
【2】尺度平方差匹配 method=CV_TM_SQDIFF_NORMED standard square dirrerence(error)
【3】 干系匹配 method=CV_TM_CCORR
这类方法接纳模板和图像间的乘法操作,以是较大的数表示匹配程度较高,0标识最坏的匹配结果.
【4】 尺度干系匹配 method=CV_TM_CCORR_NORMED
【5】 干系匹配 method=CV_TM_CCOEFF
这类方法将模版对其均值的相对值与图像对其均值的干系值举行匹配,1表示完善匹配,
-1表示糟糕的匹配,0表示没有任何干系性(随机序列).
【6】尺度干系匹配 method=CV_TM_CCOEFF_NORMED
canndy_test.py:
  1. import cv2
  2. import numpy as np
  3. def matchImg(imgPath1,imgPath2):
  4.   imgs = []
  5.   # 原始图像,用于展示
  6.   sou_img1 = cv2.imread(imgPath1)
  7.   sou_img2 = cv2.imread(imgPath2)
  8.   # 原始图像,灰度
  9.   # 最小阈值100,最大阈值500
  10.   img1 = cv2.imread(imgPath1, 0)
  11.   blur1 = cv2.GaussianBlur(img1, (3, 3), 0)
  12.   canny1 = cv2.Canny(blur1, 100, 500)
  13.   cv2.imwrite('temp1.png', canny1)
  14.   img2 = cv2.imread(imgPath2, 0)
  15.   blur2 = cv2.GaussianBlur(img2, (3, 3), 0)
  16.   canny2 = cv2.Canny(blur2, 100, 500)
  17.   cv2.imwrite('temp2.png', canny2)
  18.   target = cv2.imread('temp1.png')
  19.   template = cv2.imread('temp2.png')
  20.   # 调整显示大小
  21.   target_temp = cv2.resize(sou_img1, (350, 200))
  22.   target_temp = cv2.copyMakeBorder(target_temp, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255])
  23.   template_temp = cv2.resize(sou_img2, (200, 200))
  24.   template_temp = cv2.copyMakeBorder(template_temp, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255])
  25.   imgs.append(target_temp)
  26.   imgs.append(template_temp)
  27.   theight, twidth = template.shape[:2]
  28.   # 匹配拼图
  29.   result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
  30.   # 归一化
  31.   cv2.normalize( result, result, 0, 1, cv2.NORM_MINMAX, -1 )
  32.   min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
  33.   # 匹配后结果画圈
  34.   cv2.rectangle(target,max_loc,(max_loc[0]+twidth,max_loc[1]+theight),(0,0,255),2)
  35.   target_temp_n = cv2.resize(target, (350, 200))
  36.   target_temp_n = cv2.copyMakeBorder(target_temp_n, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255])
  37.   imgs.append(target_temp_n)
  38.   imstack = np.hstack(imgs)
  39.   cv2.imshow('stack'+str(max_loc), imstack)
  40.   cv2.waitKey(0)
  41.   cv2.destroyAllWindows()
  42. matchImg('vcode_data/out_'+str(1)+'.png','vcode_data/in_'+str(1)+'.png')
复制代码
我们测试几组数据,发现正确率拿来玩玩尚可。max_loc就是匹配出来的位置信息,我们只需要按照位置举行拖动即可。

完备步伐


完备流程
1.实例化浏览器
2.点击登陆,弹出滑动验证框
3.分别新建标签页打开配景图及拼图
4.全屏截图后按照尺寸裁剪
5.含糊匹配两张图片,获取匹配结果位置信息
6.将位置信息转为页面上的位移距离
7.拖动滑块到指定位置
  1. import time
  2. import cv2
  3. import canndy_test
  4. from selenium import webdriver
  5. from selenium.webdriver import ActionChains
  6. # 新建selenium浏览器对象,后面是geckodriver.exe下载后本地路径
  7. browser = webdriver.Firefox()
  8. # 网站登陆页面
  9. url = 'https://www.om.cn/login'
  10. # 浏览器访问登录页面
  11. browser.get(url)
  12. handle = browser.current_window_handle
  13. # 等待3s用于加载脚本文件
  14. browser.implicitly_wait(3)
  15. # 点击登陆按钮,弹出滑动验证码
  16. btn = browser.find_element_by_class_name('login_btn1')
  17. btn.click()
  18. # 获取iframe元素,切到iframe
  19. frame = browser.find_element_by_id('tcaptcha_iframe')
  20. browser.switch_to.frame(frame)
  21. time.sleep(1)
  22. # 获取背景图src
  23. targetUrl = browser.find_element_by_id('slideBg').get_attribute('src')
  24. # 获取拼图src
  25. tempUrl = browser.find_element_by_id('slideBlock').get_attribute('src')
  26. # 新建标签页
  27. browser.execute_script("window.open('');")
  28. # 切换到新标签页
  29. browser.switch_to.window(browser.window_handles[1])
  30. # 访问背景图src
  31. browser.get(targetUrl)
  32. time.sleep(3)
  33. # 截图
  34. browser.save_screenshot('temp_target.png')
  35. w = 680
  36. h = 390
  37. img = cv2.imread('temp_target.png')
  38. size = img.shape
  39. top = int((size[0] - h) / 2)
  40. height = int(h + ((size[0] - h) / 2))
  41. left = int((size[1] - w) / 2)
  42. width = int(w + ((size[1] - w) / 2))
  43. cropped = img[top:height, left:width]
  44. # 裁剪尺寸
  45. cv2.imwrite('temp_target_crop.png', cropped)
  46. # 新建标签页
  47. browser.execute_script("window.open('');")
  48. browser.switch_to.window(browser.window_handles[2])
  49. browser.get(tempUrl)
  50. time.sleep(3)
  51. browser.save_screenshot('temp_temp.png')
  52. w = 136
  53. h = 136
  54. img = cv2.imread('temp_temp.png')
  55. size = img.shape
  56. top = int((size[0] - h) / 2)
  57. height = int(h + ((size[0] - h) / 2))
  58. left = int((size[1] - w) / 2)
  59. width = int(w + ((size[1] - w) / 2))
  60. cropped = img[top:height, left:width]
  61. cv2.imwrite('temp_temp_crop.png', cropped)
  62. browser.switch_to.window(handle)
  63. # 模糊匹配两张图片
  64. move = canndy_test.matchImg('temp_target_crop.png', 'temp_temp_crop.png')
  65. # 计算出拖动距离
  66. distance = int(move / 2 - 27.5) + 2
  67. draggable = browser.find_element_by_id('tcaptcha_drag_thumb')
  68. ActionChains(browser).click_and_hold(draggable).perform()
  69. # 拖动
  70. ActionChains(browser).move_by_offset(xoffset=distance, yoffset=0).perform()
  71. ActionChains(browser).release().perform()
  72. time.sleep(10)
复制代码
  1. tips:可能会存在第一次不成功的情况,虽然拖动到了指定位置但是提示网络有问题、拼图丢失。可以进行循环迭代直到拼成功为止。通过判断iframe中id为slideBg的元素是否存在,如果成功了则不存在,失败了会刷新拼图让你重新拖动。
复制代码
  1. if(isEleExist(browser,'slideBg')):
  2.     # retry
  3.   else:
  4.     return
  5. def isEleExist(browser,id):
  6.   try:
  7.     browser.find_element_by_id(id)
  8.     return True
  9.   except:
  10.     return False
复制代码
以上就是python 模仿网站登录——滑块验证码的辨认的具体内容,更多关于python 模仿网站登录的资料请关注草根技术分享别的干系文章!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作