• 售前

  • 售后

热门帖子
入门百科

基于Pytorch版yolov5的滑块验证码破解思绪详解

[复制链接]
看不清从bm 显示全部楼层 发表于 2021-10-25 19:59:34 |阅读模式 打印 上一主题 下一主题
媒介

本文将使用pytorch框架的目标辨认技术实现滑块验证码的破解。我们这里选择了yolov5算法
例:输入图像

输出图像

可以看到经过检测之后,我们能很正确的定位到缺口的位置,并且能得到缺口的坐标,如许一来我们就能很轻松的实现滑动验证码的破解。
一.前期工作

yolov系列是常用的目标检测算法,yolov5不仅设置简单,而且在速度上也有不小的提拔,我们很轻易就能练习我们自己的数据集。
YOLOV5 Pytorch版本GIthub网址感谢这位作者的代码。
下载之后,是如许的格式
  1. ---data/
  2.         Annotations/ 存放图片的标注文件(.xml)
  3.         images/ 存放待训练的图片
  4.         ImageSets/ 存放划分数据集的文件
  5.         labels/ 存放图片的方框信息
复制代码
此中只须要修改Annotations和images两个文件夹。
起首我们将待练习的图片放入images
数据集要感谢这位大神的整理https://github.com/tzutalin/labelImg,在这个底子上我增加了50张来自腾讯的验证码图片
数据集已上传百度云
链接: https://pan.baidu.com/s/1XS5KVoXqGHglfP0mZ3HJLQ
提取码: wqi8

然后我们须要对其进行标注,告诉计算机我们希望它辨认什么内容。这时间我们须要精灵标注这款软件。免费而且功能强盛,五星好评!

第一步选择images文件夹,第二步有几类就写几类,发起用英文。这里只有一类,即为缺失快的位置,定名为target。注意标注的时间要左右恰好卡住,否则得到的坐标就不精准。
标注完成后,点击导出,文件格式不消动,直接点确定,就会在images/outputs文件夹生成我们的标注文件。全部复制到Annotations文件夹即可。
回到主目次,运行makeTxt.py和voc_label.py,makeTxt直接运行即可,voc_label须要修改classes的值,这次只有一target
  1. import xml.etree.ElementTree as ET
  2. import pickle
  3. import os
  4. # os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表
  5. from os import listdir, getcwd
  6. from os.path import join
  7. sets = ['train', 'test', 'val']
  8. classes = ['target'] #之前标注时有几个类,这里就输入几个类
  9. """
  10. ............  
  11. """
复制代码
进入data文件夹,修改coco.yaml的内容
  1. # COCO 2017 dataset http://cocodataset.org
  2. # Download command: bash yolov5/data/get_coco2017.sh
  3. # Train command: python train.py --data ./data/coco.yaml
  4. # Dataset should be placed next to yolov5 folder:
  5. #  /parent_folder
  6. #   /coco
  7. #   /yolov5
  8. # train and val datasets (image directory or *.txt file with image paths)
  9. train: ../coco/train2017.txt # 118k images
  10. val: ../coco/val2017.txt # 5k images
  11. test: ../coco/test-dev2017.txt # 20k images for submission to https://competitions.codalab.org/competitions/20794
  12. # number of classes
  13. nc: 1
  14. # class names
  15. names: ['target']
  16. # Print classes
  17. # with open('data/coco.yaml') as f:
  18. #  d = yaml.load(f, Loader=yaml.FullLoader) # dict
  19. #  for i, x in enumerate(d['names']):
  20. #   print(i, x)
复制代码
再进入models文件夹,修改yolov5s.yaml的内容
  1. nc: 1 # number of classes
  2. depth_multiple: 0.33 # model depth multiple
  3. width_multiple: 0.50 # layer channel multiple
  4. """
  5. ''''''''''''
  6. """
复制代码
至此设置环节终于竣事了,可以开始练习了!
打开train.py,我们一样平常只须要修改–weights,–cfg,–data,–epochs几个设置即可
  1. parser = argparse.ArgumentParser()
  2. parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path')
  3. parser.add_argument('--cfg', type=str, default='models/yolov5s.yaml', help='model.yaml path')
  4. parser.add_argument('--data', type=str, default='data/coco.yaml', help='data.yaml path')
  5. parser.add_argument('--hyp', type=str, default='data/hyp.scratch.yaml', help='hyperparameters path')
  6. parser.add_argument('--epochs', type=int, default=300)
  7. parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs')
  8. parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='[train, test] image sizes')
  9. parser.add_argument('--rect', action='store_true', help='rectangular training')
  10. parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')
  11. parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
  12. parser.add_argument('--notest', action='store_true', help='only test final epoch')
  13. parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')
  14. parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')
  15. parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
  16. parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')
  17. parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')
  18. parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
  19. parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')
  20. parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class')
  21. parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer')
  22. parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
  23. parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')
  24. parser.add_argument('--log-imgs', type=int, default=16, help='number of images for W&B logging, max 100')
  25. parser.add_argument('--log-artifacts', action='store_true', help='log artifacts, i.e. final trained model')
  26. parser.add_argument('--workers', type=int, default=4, help='maximum number of dataloader workers')
  27. parser.add_argument('--project', default='runs/train', help='save to project/name')
  28. parser.add_argument('--name', default='exp', help='save to project/name')
  29. parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
  30. opt = parser.parse_args()
复制代码
直接运行train.py,开始练习!
。。。。。。。。。。。。。。。。
练习完成后,进入runs/train/exp/weights,我们复制best.pt到主目次。
最后,我们打开datect.py,修改几个属性
  1. parser = argparse.ArgumentParser()
  2.   parser.add_argument('--weights', nargs='+', type=str, default='best.pt', help='model.pt path(s)')
  3.   parser.add_argument('--source', type=str, default='test.jpg', help='source') # file/folder, 0 for webcam
  4.   parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
  5.   parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
  6.   parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
  7.   parser.add_argument('--device', default='0', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
  8.   parser.add_argument('--view-img', action='store_true', help='display results')
  9.   parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
  10.   parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
  11.   parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
  12.   parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
  13.   parser.add_argument('--augment', action='store_true', help='augmented inference')
  14.   parser.add_argument('--update', action='store_true', help='update all models')
  15.   parser.add_argument('--project', default='runs/detect', help='save results to project/name')
  16.   parser.add_argument('--name', default='exp', help='save results to project/name')
  17.   parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
  18.   opt = parser.parse_args()
复制代码
–source属性我们可以先修改为data/images,对自己的数据集进行辨认看看可否正知辨认。
小Tips,如果实行后不报错,但没有检测框的话,试试看修改–device为cpu,cuda版本太低会导致使用gpu没有检测框(问就是被这个小题目迫害了很久 --_–)。
最后在112行左右的位置,添加一个print

这时实行程序就会返回方框的位置信息和自信度了

我们的前驱工作终于完成了~
二.编写爬虫

1.寻找合适的网站

经过一番搜寻,最后锁定了https://007.qq.com/online.html
因为它的网站布局很方便我们的使用。
2.导入依赖库

这里我们接纳selenium来模仿人类的使用。
关于selenium的安装和webdriver的安装方法本文不作延伸。
  1. from selenium import webdriver
  2. from selenium.webdriver.common.action_chains import ActionChains
  3. import requests,re
  4. import os
  5. import requests
  6. import re
  7. import time
  8. from selenium.webdriver import ActionChains
复制代码
3.编写破解程序

访问网站,发现破解之前要依次点击

编写代码
  1. def run()
  2.         driver = webdriver.Chrome()
  3.        
  4.         headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36"}
  5.         #伪装请求头
  6.        
  7.        
  8.                 
  9.         driver.get('https://007.qq.com/online.html') #访问网站
  10.        
  11.         driver.find_element_by_xpath('/html/body/div[1]/section[1]/div/div/div/div[2]/div[1]/a[2]').click()
  12.         driver.find_element_by_xpath('//*[@id="code"]').click()
  13.         #模拟点击操作
复制代码
继承

这里便是我们要辨认的图片,不过直接定位的话并不能定位到,因为这段代码是由iframe包裹着的,我们须要先定位到这个iframe
  1. time.sleep(2)      #休眠2秒,防止报错  
  2.         driver.switch_to_frame("tcaptcha_iframe") #根据iframe的id定位到iframe
  3.         target = driver.find_element_by_xpath("/html/body/div/div[3]/div[2]/div[1]/div[2]/img").get_attribute("src")
  4.         #得到图片的原地址
  5.        
  6.         response = requests.get(target,headers=headers)        #访问图片地址
  7.          
  8.         img = response.content
  9.         with open( 'test.jpg','wb' ) as f:
  10.           f.write(img)                #将图片保存到主目录,命名为test.jpg
复制代码
现在图片也有了,检测程序也预备好了,那么开始检测吧!
  1. '''
  2.         os.popen()的用法,简单来说就是执行cmd命令,并得到cmd的返回值
  3.         这里是执行detect.py
  4.         '''
  5.        
  6.         result = os.popen("python detect.py").readlines() #执行目标检测程序
  7.         list = []
  8.         for line in result:
  9.           list.append(line)   #将cmd的返回信息存入列表
  10.         print(list)
  11.         a = re.findall("(.*):(.*]).(.*)\\n",list[-4]) #获得图片的位置信息
  12.         print(a)
  13.         print(len(a))
  14.         if len(a) != 0:     #如果能检测到方框
  15.           tensor=a[0][1]
  16.           pro = a[0][2]
  17.           list_=tensor[2:-1].split(",")
  18.           
  19.           location = []
  20.           for i in list_:
  21.             print(i)
  22.             b = re.findall("tensor(.*)",i)[0]
  23.             location.append(b[1:-2])
  24.           #提取出来方框左上角的xy和右下角的xy
  25.           drag1 = driver.find_element_by_xpath('/html/body/div/div[3]/div[2]/div[2]/div[2]/div[1]')
  26.           #定位到拖动按钮处
  27.           
  28.           action_chains = ActionChains(driver) #实例化鼠标操作类
  29.           action_chains.drag_and_drop_by_offset(drag1, int(int(location[2])/2-85), 0).perform()
  30.           #模拟鼠标按住并拖动距离 X 后再放开
  31.           input("等待操作")  
  32.           driver.quit()
  33.         else:
  34.           driver.quit()
  35.           print("未能识别")   
复制代码
这里着重说一下
  1. action_chains.drag_and_drop_by_offset(drag1, int(int(location[2])/2-85), 0).perform()
复制代码
为什么要拖
  1. int(int(location[2])/2-85)
复制代码
远。
起首
  1. location
复制代码
这个列表的格式为
  1. [左上x,左上y,右下x,右下y]
复制代码
  1. location[2]
复制代码
即为取出右下角的x值。
我们生存到本地的验证码图片分辨率如下

但网站显示的图片巨细
  1. x轴
复制代码
刚好为本舆图片的一半,以是
  1. int(location[2]/2)
复制代码
得到的便是

但是待拖动的方块自己隔断左边还有一定隔断,通过分析发现

这个小方块的最左边隔断图片的最左边的隔断即为红框中的26,即

26+68-10=84,因为这个10是试出来的长度,我们就令这段隔断为85吧
至此
  1. int(int(location[2])/2-85)
复制代码
的由来也表明清楚了。
大功告成啦,那让我们看一遍演示吧!

selenium完备代码如下
  1. from selenium import webdriver
  2. from selenium.webdriver.common.action_chains import ActionChains
  3. import requests,re
  4. import os
  5. import requests
  6. import re
  7. import time
  8. from selenium.webdriver import ActionChainsdef run()        driver = webdriver.Chrome()                headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36"}        #伪装请求头         driver.get('https://007.qq.com/online.html') #访问网站        driver.find_element_by_xpath('/html/body/div[1]/section[1]/div/div/div/div[2]/div[1]/a[2]').click()        driver.find_element_by_xpath('//*[@id="code"]').click()        #模仿点击使用  time.sleep(2)      #休眠2秒,防止报错  
  9.         driver.switch_to_frame("tcaptcha_iframe") #根据iframe的id定位到iframe
  10.         target = driver.find_element_by_xpath("/html/body/div/div[3]/div[2]/div[1]/div[2]/img").get_attribute("src")
  11.         #得到图片的原地址
  12.        
  13.         response = requests.get(target,headers=headers)        #访问图片地址
  14.          
  15.         img = response.content
  16.         with open( 'test.jpg','wb' ) as f:
  17.           f.write(img)                #将图片保存到主目录,命名为test.jpg        '''        os.popen()的用法,简单来说就是实行cmd下令,并得到cmd的返回值        这里是实行detect.py        '''        result = os.popen("python detect.py").readlines() #实行目标检测程序        list = []        for line in result:          list.append(line)   #将cmd的返复书息存入列表        print(list)        a = re.findall("(.*):(.*]).(.*)\\n",list[-4]) #得到图片的位置信息        print(a)        print(len(a))        if len(a) != 0:     #如果能检测到方框          tensor=a[0][1]          pro = a[0][2]          list_=tensor[2:-1].split(",")                    location = []          for i in list_:            print(i)            b = re.findall("tensor(.*)",i)[0]            location.append(b[1:-2])          #提取出来方框左上角的xy和右下角的xy          drag1 = driver.find_element_by_xpath('/html/body/div/div[3]/div[2]/div[2]/div[2]/div[1]')           #定位到拖动按钮处          action_chains = ActionChains(driver) #实例化鼠标使用类          action_chains.drag_and_drop_by_offset(drag1, int(int(location[2])/2-85), 0).perform()          #模仿鼠标按住并拖动隔断 X 后再放开          input("等候使用")            driver.quit()         else:          driver.quit()           print("未能辨认")    while True:     run()
复制代码
到此这篇关于基于Pytorch版yolov5的滑块验证码破解思路详解的文章就介绍到这了,更多相关Pytorch滑块验证码破解内容请搜刮脚本之家从前的文章或继承欣赏下面的相关文章希望各人以后多多支持脚本之家!

本帖子中包含更多资源

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

x

帖子地址: 

回复

使用道具 举报

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

本版积分规则

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

  • 微信公众号

  • 商务合作