日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2023/12/9 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于Pytorch版yolov5的滑块验证码破解思路 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

基于Pytorch版yolov5的滑塊驗(yàn)證碼破解思路

    • 前言
    • 一.前期工作
    • 二.編寫(xiě)爬蟲(chóng)
      • 1.尋找合適的網(wǎng)站
      • 2.導(dǎo)入依賴(lài)庫(kù)
      • 3.編寫(xiě)破解程序

前言

本文將使用pytorch框架的目標(biāo)識(shí)別技術(shù)實(shí)現(xiàn)滑塊驗(yàn)證碼的破解。我們這里選擇了yolov5算法

例:輸入圖像

輸出圖像

可以看到經(jīng)過(guò)檢測(cè)之后,我們能很準(zhǔn)確的定位到缺口的位置,并且能得到缺口的坐標(biāo),這樣一來(lái)我們就能很輕松的實(shí)現(xiàn)滑動(dòng)驗(yàn)證碼的破解。

一.前期工作

yolov系列是常用的目標(biāo)檢測(cè)算法,yolov5不僅配置簡(jiǎn)單,而且在速度上也有不小的提升,我們很容易就能訓(xùn)練我們自己的數(shù)據(jù)集。
YOLOV5 Pytorch版本GIthub網(wǎng)址感謝這位作者的代碼。

下載之后,是這樣的格式

---data/Annotations/ 存放圖片的標(biāo)注文件(.xml)images/ 存放待訓(xùn)練的圖片ImageSets/ 存放劃分?jǐn)?shù)據(jù)集的文件labels/ 存放圖片的方框信息

其中只需要修改Annotations和images兩個(gè)文件夾。
首先我們將待訓(xùn)練的圖片放入images

數(shù)據(jù)集要感謝這位大神的整理https://github.com/tzutalin/labelImg,在這個(gè)基礎(chǔ)上我增加了50張來(lái)自騰訊的驗(yàn)證碼圖片

數(shù)據(jù)集已上傳百度云

鏈接:https://pan.baidu.com/s/1Ny_KUm1LhsLdLrKAVQH2XA
提取碼:4v79

然后我們需要對(duì)其進(jìn)行標(biāo)注,告訴計(jì)算機(jī)我們希望它識(shí)別什么內(nèi)容。這時(shí)候我們需要精靈標(biāo)注這款軟件。免費(fèi)而且功能強(qiáng)大,五星好評(píng)!

第一步選擇images文件夾,第二步有幾類(lèi)就寫(xiě)幾類(lèi),建議用英文。這里只有一類(lèi),即為缺失快的位置,命名為target。注意標(biāo)注的時(shí)候要左右恰好卡住,不然獲得的坐標(biāo)就不精準(zhǔn)。

標(biāo)注完成后,點(diǎn)擊導(dǎo)出,文件格式不用動(dòng),直接點(diǎn)確定,就會(huì)在images/outputs文件夾生成我們的標(biāo)注文件。全部復(fù)制到Annotations文件夾即可。

回到主目錄,運(yùn)行makeTxt.py和voc_label.py,makeTxt直接運(yùn)行即可,voc_label需要修改classes的值,這次只有一target

import xml.etree.ElementTree as ET import pickle import os # os.listdir() 方法用于返回指定的文件夾包含的文件或文件夾的名字的列表 from os import listdir, getcwd from os.path import joinsets = ['train', 'test', 'val'] classes = ['target'] #之前標(biāo)注時(shí)有幾個(gè)類(lèi),這里就輸入幾個(gè)類(lèi)"""............ """

進(jìn)入data文件夾,修改coco.yaml的內(nèi)容

# COCO 2017 dataset http://cocodataset.org # Download command: bash yolov5/data/get_coco2017.sh # Train command: python train.py --data ./data/coco.yaml # Dataset should be placed next to yolov5 folder: # /parent_folder # /coco # /yolov5# train and val datasets (image directory or *.txt file with image paths) train: ../coco/train2017.txt # 118k images val: ../coco/val2017.txt # 5k images test: ../coco/test-dev2017.txt # 20k images for submission to https://competitions.codalab.org/competitions/20794# number of classes nc: 1# class names names: ['target']# Print classes # with open('data/coco.yaml') as f: # d = yaml.load(f, Loader=yaml.FullLoader) # dict # for i, x in enumerate(d['names']): # print(i, x)

再進(jìn)入models文件夾,修改yolov5s.yaml的內(nèi)容

nc: 1 # number of classes depth_multiple: 0.33 # model depth multiple width_multiple: 0.50 # layer channel multiple """ '''''''''''' """

至此配置環(huán)節(jié)終于結(jié)束了,可以開(kāi)始訓(xùn)練了!

打開(kāi)train.py,我們一般只需要修改–weights,–cfg,–data,–epochs幾個(gè)設(shè)置即可

parser = argparse.ArgumentParser() parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path') parser.add_argument('--cfg', type=str, default='models/yolov5s.yaml', help='model.yaml path') parser.add_argument('--data', type=str, default='data/coco.yaml', help='data.yaml path') parser.add_argument('--hyp', type=str, default='data/hyp.scratch.yaml', help='hyperparameters path') parser.add_argument('--epochs', type=int, default=300) parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs') parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='[train, test] image sizes') parser.add_argument('--rect', action='store_true', help='rectangular training') parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training') parser.add_argument('--nosave', action='store_true', help='only save final checkpoint') parser.add_argument('--notest', action='store_true', help='only test final epoch') parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check') parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters') parser.add_argument('--bucket', type=str, default='', help='gsutil bucket') parser.add_argument('--cache-images', action='store_true', help='cache images for faster training') parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training') parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%') parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class') parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer') parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode') parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify') parser.add_argument('--log-imgs', type=int, default=16, help='number of images for W&B logging, max 100') parser.add_argument('--log-artifacts', action='store_true', help='log artifacts, i.e. final trained model') parser.add_argument('--workers', type=int, default=4, help='maximum number of dataloader workers') parser.add_argument('--project', default='runs/train', help='save to project/name') parser.add_argument('--name', default='exp', help='save to project/name') parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment') opt = parser.parse_args()

直接運(yùn)行train.py,開(kāi)始訓(xùn)練!
。。。。。。。。。。。。。。。。

訓(xùn)練完成后,進(jìn)入runs/train/exp/weights,我們復(fù)制best.pt到主目錄。

最后,我們打開(kāi)datect.py,修改幾個(gè)屬性

parser = argparse.ArgumentParser()parser.add_argument('--weights', nargs='+', type=str, default='best.pt', help='model.pt path(s)')parser.add_argument('--source', type=str, default='test.jpg', help='source') # file/folder, 0 for webcamparser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')parser.add_argument('--device', default='0', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--view-img', action='store_true', help='display results')parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')parser.add_argument('--augment', action='store_true', help='augmented inference')parser.add_argument('--update', action='store_true', help='update all models')parser.add_argument('--project', default='runs/detect', help='save results to project/name')parser.add_argument('--name', default='exp', help='save results to project/name')parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')opt = parser.parse_args()

–source屬性我們可以先修改為data/images,對(duì)自己的數(shù)據(jù)集進(jìn)行識(shí)別看看能否正常識(shí)別。
小Tips,如果執(zhí)行后不報(bào)錯(cuò),但沒(méi)有檢測(cè)框的話,試試看修改–device為cpu,cuda版本太低會(huì)導(dǎo)致使用gpu沒(méi)有檢測(cè)框(問(wèn)就是被這個(gè)小問(wèn)題迫害了很久 --_–)。

最后在112行左右的位置,添加一個(gè)print
這時(shí)執(zhí)行程序就會(huì)返回方框的位置信息和自信度了

我們的前驅(qū)工作終于完成了~

二.編寫(xiě)爬蟲(chóng)

1.尋找合適的網(wǎng)站

經(jīng)過(guò)一番搜尋,最后鎖定了https://007.qq.com/online.html

因?yàn)樗木W(wǎng)站結(jié)構(gòu)很方便我們的操作。

2.導(dǎo)入依賴(lài)庫(kù)

這里我們采用selenium來(lái)模擬人類(lèi)的操作。
關(guān)于selenium的安裝和webdriver的安裝方法本文不作延伸。

from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains import requests,re import os import requests import re import time from selenium.webdriver import ActionChains

3.編寫(xiě)破解程序

訪問(wèn)網(wǎng)站,發(fā)現(xiàn)破解之前要依次點(diǎn)擊
編寫(xiě)代碼

def 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"}#偽裝請(qǐng)求頭driver.get('https://007.qq.com/online.html') #訪問(wèn)網(wǎng)站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()#模擬點(diǎn)擊操作

繼續(xù)
這里便是我們要識(shí)別的圖片,不過(guò)直接定位的話并不能定位到,因?yàn)檫@段代碼是由iframe包裹著的,我們需要先定位到這個(gè)iframe

time.sleep(2) #休眠2秒,防止報(bào)錯(cuò) driver.switch_to_frame("tcaptcha_iframe") #根據(jù)iframe的id定位到iframetarget = driver.find_element_by_xpath("/html/body/div/div[3]/div[2]/div[1]/div[2]/img").get_attribute("src")#得到圖片的原地址response = requests.get(target,headers=headers) #訪問(wèn)圖片地址img = response.contentwith open( 'test.jpg','wb' ) as f:f.write(img) #將圖片保存到主目錄,命名為test.jpg

現(xiàn)在圖片也有了,檢測(cè)程序也準(zhǔn)備好了,那么開(kāi)始檢測(cè)吧!

'''os.popen()的用法,簡(jiǎn)單來(lái)說(shuō)就是執(zhí)行cmd命令,并得到cmd的返回值這里是執(zhí)行detect.py'''result = os.popen("python detect.py").readlines() #執(zhí)行目標(biāo)檢測(cè)程序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: #如果能檢測(cè)到方框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])#提取出來(lái)方框左上角的xy和右下角的xydrag1 = driver.find_element_by_xpath('/html/body/div/div[3]/div[2]/div[2]/div[2]/div[1]') #定位到拖動(dòng)按鈕處action_chains = ActionChains(driver) #實(shí)例化鼠標(biāo)操作類(lèi)action_chains.drag_and_drop_by_offset(drag1, int(int(location[2])/2-85), 0).perform()#模擬鼠標(biāo)按住并拖動(dòng)距離 X 后再放開(kāi)input("等待操作") driver.quit() else:driver.quit() print("未能識(shí)別")

這里著重說(shuō)一下

action_chains.drag_and_drop_by_offset(drag1, int(int(location[2])/2-85), 0).perform()

為什么要拖 int(int(location[2])/2-85) 遠(yuǎn)。

首先location這個(gè)列表的格式為[左上x(chóng),左上y,右下x,右下y],location[2]即為取出右下角的x值。

我們保存到本地的驗(yàn)證碼圖片分辨率如下

但網(wǎng)站顯示的圖片大小

x軸剛好為本地圖片的一半,所以int(location[2]/2)得到的便是

但是待拖動(dòng)的方塊本身距離左邊還有一定距離,通過(guò)分析發(fā)現(xiàn)

這個(gè)小方塊的最左邊距離圖片的最左邊的距離即為紅框中的26,即

26+68-10=84,因?yàn)檫@個(gè)10是試出來(lái)的長(zhǎng)度,我們就令這段距離為85吧

至此 int(int(location[2])/2-85) 的由來(lái)也解釋清楚了。
大功告成啦,那讓我們看一遍演示吧!


selenium完整代碼如下

from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains import requests,re import os import requests import re import time 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"}#偽裝請(qǐng)求頭 driver.get('https://007.qq.com/online.html') #訪問(wèn)網(wǎng)站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()#模擬點(diǎn)擊操作time.sleep(2) #休眠2秒,防止報(bào)錯(cuò) driver.switch_to_frame("tcaptcha_iframe") #根據(jù)iframe的id定位到iframetarget = driver.find_element_by_xpath("/html/body/div/div[3]/div[2]/div[1]/div[2]/img").get_attribute("src")#得到圖片的原地址response = requests.get(target,headers=headers) #訪問(wèn)圖片地址img = response.contentwith open( 'test.jpg','wb' ) as f:f.write(img) #將圖片保存到主目錄,命名為test.jpg'''os.popen()的用法,簡(jiǎn)單來(lái)說(shuō)就是執(zhí)行cmd命令,并得到cmd的返回值這里是執(zhí)行detect.py'''result = os.popen("python detect.py").readlines() #執(zhí)行目標(biāo)檢測(cè)程序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: #如果能檢測(cè)到方框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])#提取出來(lái)方框左上角的xy和右下角的xydrag1 = driver.find_element_by_xpath('/html/body/div/div[3]/div[2]/div[2]/div[2]/div[1]') #定位到拖動(dòng)按鈕處action_chains = ActionChains(driver) #實(shí)例化鼠標(biāo)操作類(lèi)action_chains.drag_and_drop_by_offset(drag1, int(int(location[2])/2-85), 0).perform()#模擬鼠標(biāo)按住并拖動(dòng)距離 X 后再放開(kāi)input("等待操作") driver.quit() else:driver.quit() print("未能識(shí)別") while True: run()

總結(jié)

以上是生活随笔為你收集整理的基于Pytorch版yolov5的滑块验证码破解思路的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。