百度旋转图片验证

Python-实现自动旋转图片通过百度安全验证

整体思路:

(1)建立图片库。

建立一个图片库,图片库里每张图片都有一个旋转角度(用图片的名称记录每张图片到正确图片的旋转角度)。

(2)计算需要旋转的角度。

将当前要进行旋转验证的图片和图片库的图片进行比较,找出相似度最高的那张图片,就可以得到当前验证的图片需要旋转的角度。

(3)计算需要拖动的距离。

根据网页上的拖动框长度和拖动角度的比例计算出当前需要拖动button的距离。

(4)拖动button进行验证。

进行按下button-拖动距离-释放button,从而实现验证通过。

1. 建立图片库

1.1 抓取图片

找一个安全验证的页面,用selenium截取页面快照,然后裁剪出下面的图片。图片的名称用x.png标记,其中x为0,1,2,3,4,……
使用之前需要先安装selenium库,如果使用有问题可以参考链接https://blog.csdn.net/liujingliuxingjiang/article/details/120726198?spm=1001.2014.3001.5501

注意:图片保存的路径要用英文,不要包含中文,后面有些函数不支持路径含有中文的(比如相似度计算的那个函数)。
在这里插入图片描述

import selenium
import time
from selenium import webdriver
from PIL import Image
from selenium.webdriver.common.keys import Keys
path =r"C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chromedriver.exe"
browser = webdriver.Chrome(executable_path=path)
#抓取500张图片,这些图片有很多是重复的
for i in range(0,500,1):
    browser.get("https://wappass.baidu.com/static/captcha/tuxing.html?ak=2ef521ec36290baed33d66de9b16f625&backurl=http%3A%2F%2Ftieba.baidu.com%2Fp%2F3982352452&timestamp=1630048735&signature=72a227fed2dc24a90bcf68b45837af6c")
    time.sleep(10)#这里需要等一会儿,页面加载好,不然读取不到xpath定位的元素
    print(browser.page_source)
    input = browser.find_element_by_xpath('//div[@class="vcode-spin-faceboder"]')
    time.sleep(5)
    browser.save_screenshot(r'E:\login.png')
    left=input.location['x']
    top=input.location['y']
    right=left+input.size['width']
    bottom=top+input.size['height']

    im=Image.open(r'E:\login.png')
    mg=im.crop((left,top,right,bottom))
    #保存截图,命名为0.png,1.png……
    mg.save(r'E:\baidu_safe\{}.png'.format(i))

1.2 筛选图片

我截取并保存了500张图片,基本上是涵盖了现在的所有验证图片。这500张图片中有很多图片是一样的,只是角度不同,我们如果用人眼筛选和删除重复的图片,工作量太大了,眼睛也受不了。所以,这里还是采用脚本进行筛选。每两张图片进行比较,如果相似度大于一个阈值,就删除其中一张,保留另一张。

下面要引入相似度计算的函数,这是我直接用别人提供好的,这个算法不是我写的。https://blog.csdn.net/liu506039293/article/details/102696486这是原文的链接,感谢作者提供的算法!

#计算相似度
def img_similarity(img1_path,img2_path):
    """
    :param img1_path: 图片1路径
    :param img2_path: 图片2路径
    :return: 图片相似度
    """
    try:
        # 读取图片
        img1 = cv2.imread(img1_path, cv2.IMREAD_GRAYSCALE)
        img2 = cv2.imread(img2_path, cv2.IMREAD_GRAYSCALE)

        # 初始化ORB检测器
        orb = cv2.ORB_create()
        kp1, des1 = orb.detectAndCompute(img1, None)
        kp2, des2 = orb.detectAndCompute(img2, None)

        # 提取并计算特征点
        bf = cv2.BFMatcher(cv2.NORM_HAMMING)

        # knn筛选结果
        matches = bf.knnMatch(des1, trainDescriptors=des2, k=2)

        # 查看最大匹配点数目
        good = [m for (m, n) in matches if m.distance < 0.75 * n.distance]
        # print(len(good))
        # print(len(matches))
        similary = len(good) / len(matches)
        # print("两张图片相似度为:%s" % similary)
        return similary

    except:
        print('无法计算两张图片相似度')
        return '0'
#对于相似度高的图片,只保留其中一张图片,其他图片加入到删除的列表中,后续进行删除
def detele_same_img():
    remove_list = []
    for i in range(500):
        for j in range(i+1,501):
            img1_path = r'E:\baidu_safe\{}.png'.format(i)
            img2_path = r'E:\baidu_safe\{}.png'.format(j)
            similary = img_similarity(img1_path, img2_path)
            if similary > 0.5:#可以根据实际情况调整这个阈值
                print(similary)
                print("i:{},j:{}".format(i,j))
                remove_file = r'E:\baidu_safe\{}.png'.format(j)
                if remove_file not in remove_list:
                    remove_list.append(remove_file)           
#删除相似度高的图片(我们这里认为相似度超过了一个阈值就是同一张图片,只不过角度不同)
def delete_files(remove_list):
    for file in remove_list:
        os.remove(file)

1.3 旋转图片得到所有角度的图片

旋转图片有很多库函数可以实现,需要选择旋转后空白地方的像素采用邻近像素填充的方式进行旋转,不然图片会失真太多,影响最终的结果。

我这里采用的是的opencv库函数,需要安装opencv-python,如果安装失败,可以尝试在后面加长一点的timeout,默认是15秒超时,完整的命令:

pip install opencv-python --timeout 100。

将每张图片建立一个文件夹,文件夹的名字就是抓取图片的名字的数字部分。文件夹中的图片命名从1.png到360.png,分别对应旋转1到360度生成的新图片。

#图片旋转,生成各个角度的图片
import cv2
def rotation_img(img_path):
    file_list = os.listdir(img_path)
    for file in file_list:
        file_index = file.replace(".png",'')
        curr_file = r'E:\baidu_safe\\' + file
        dir_path = r'E:\baidu_safe\all_angles\{}'.format(file_index)
        if os.path.exists(dir_path):
            pass
        else:
            os.mkdir(dir_path)#新建文件夹,文件夹的名字是原始图片名字出去.png部分
            for i in range(1,361):#把一张图片旋转1度~360度,保证每个角度的图片都有一张,共360张
            img = cv2.imread(curr_file)
            rows, cols, channel = img.shape
            M = cv2.getRotationMatrix2D((cols/2, rows/2), i, 1
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值