python实现过顶象滑块

前言

看了网上很多博主都有过顶象滑块的方案,要么是代码不全,要么就是写的不够详细,自己研究了下把整个实现过程记录下来。

实现步骤

  1. 下载bg图与icon图;
  2. 还原bg图;
  3. 使用icon图匹配bg图缺口位置,获得坐标;
  4. 模拟请求参数,获取返回信息;

下载bg图与icon图

url前缀网址是一样的,只需要获取返回的图片后缀

   bg_url = f'https://static.dingxiang-inc.com/picture{p1}'
   icon_url = f'https://static.dingxiang-inc.com/picture{p2}'

问题来了,怎样获取前缀,使用api 携带akc参数获取
api:https://cap.dingxiang-inc.com/api/v1
请求param请求param
参考代码

    import requests
def get_img():
	# 返回的aid_dx ,sid后面需要用到
	# p1、p2 是bg 与 icon图
    headers = {
        'Accept': '*/*',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'Origin': 'https://m.airchina.com.cn',
        'Pragma': 'no-cache',
        'Referer': 'https://m.airchina.com.cn/',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'cross-site',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
        'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="102", "Google Chrome";v="102"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
    }
    random.random() * 100000000
    aid_dx = f'dx-{str(int(time.time() * 1000))}-{str(int(random.random() * 100000000))}-1' 
    params = (
        ('w', '300'),
        ('h', '150'),
        ('s', '50'),
        ('ak', '5f6727ec854786a86cd4c3c171d13499'),
        ('c', '63490534hEK47XdXUPbCVcFE1MpdpRs4blnVT8w1'),
        ('jsv', '1.5.28.117'),
        ('aid', aid_dx),
        ('wp', '1'),
        ('de', '0'),
        ('uid', ''),
        ('lf', '0'),
        ('tpc', ''),
        ('cid', '78726764'),
        ('_r', '0.24678465468631372'),
    )

    response = requests.get('https://cap.dingxiang-inc.com/api/a', headers=headers, params=params)
    res = response.json()
    return [aid_dx, res['sid'], res['p1'], res['p2']]

返回的数据,其实只有sid,p1, p2有用
在这里插入图片描述

还原bg图

下载的bg图,实际上是乱序的,是由一定的规则排序,可以理解成打乱成12条图片

  • 下载的原图
    在这里插入图片描述
  • 还原后的图
    在这里插入图片描述
还原算法是用js实现,有兴趣的可以去看下算法,原理是用图片编号,生成对应的一个数组,对应的算法用python改写

1.用图片编号,生成数组

  • path_code,就是p1后面那一串字符

  • 贴python实现代码,python还原算法自己写的,可以自己敲一遍,想下怎样实现的
    在这里插入图片描述

  • 贴上js原生实现方法,下面就是生成的数组
    在这里插入图片描述

2.使用数组还原完整图片

  • 还原图片的代码
    import time
    import re
    from urllib.parse import urlencode
    import random
    import requests
    import cv2
    import numpy as np
    from PIL import Image
    import matplotlib.pyplot as plt
    import execjs
    import json
    
    # 读取bg图
    img = Image.open('./img/bg.jpg')
    # _seq 是 上面返回的数组
    def gen(_seq, _img):
        a = 200
        np_image = np.array(_img)
        new_np_img = np.zeros((200, 400, 3), dtype=np.uint8)
        for u in range(0, 32):
            c = _seq[u] % 32 * 12
            xpos = u % 32 * 12
            slice_img = np_image[0:(0 + a), c:(c + 12)]
            n = len(slice_img[0])
            new_np_img[0:(0 + a), xpos:(xpos + n)] = slice_img
        return new_np_img
    new_img = gen(seq, img)
    # 保存还原图片
    cv2.imwrite('./img/new_bg.png', new_img)
    
  • 代码中 200,400,是新图片的尺寸,12是原图片被切成12块,需要还原

使用icon图匹配bg图缺口位置,获得坐标

1.生成坐标

  • 贴识别代码
    # 顶象滑块识别
    def dXImgSlider(origin, sliderImg):
        slider = cv2.imread(sliderImg)
        originImg = cv2.imread(origin)
        bgImg = cv2.cvtColor(originImg, cv2.COLOR_BGR2GRAY)
        sliderImg = cv2.cvtColor(slider, cv2.COLOR_BGR2GRAY)
        # 反相
        frame_gray_c = sliderImg.copy()
        height, width = frame_gray_c.shape
        for i in range(height):
            for j in range(width):
                pv = frame_gray_c[i, j]
                frame_gray_c[i][j] = 255 - pv
    
        # 高斯滤波
        imgGaussianBlur1 = cv2.GaussianBlur(frame_gray_c, (3, 3), 0)
        imgGaussianBlur2 = cv2.GaussianBlur(bgImg, (7, 7), 0)
    
        # 获取模板图像的高和宽
        th, tw = sliderImg.shape[:2]
        # 使用标准相关系数匹配,1表示完美匹配,-1表示糟糕的匹配,0表示没有任何相关性
        result = cv2.matchTemplate(imgGaussianBlur2, imgGaussianBlur1, cv2.TM_CCOEFF_NORMED)
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
        tl = max_loc
        br = (tl[0] + tw, tl[1] + th)
    
        # 绘制识别框
        im = cv2.rectangle(originImg, tl, br, (0, 0, 255), 2)
        t = time.time() - 60 * 60 * 24 * 30
        time_string = time.strftime("%Y%m%d%H%M%S", time.localtime(t))
        # save_path = "./img/result" + time_string + ".jpg"
        save_path = "./img/result1.jpg"
        cv2.imwrite(save_path, im)
        resObj = [tl[0], tl[1], br[0], br[1]]
    
        # 需要与实际提交的尺寸匹配,上面生成的 新bg图尺寸与实际尺寸不一样,需要把坐标转换
        # 新坐标
        resObj  = [int(x * 300/400) for x in resObj]
    
        print(resObj)
        return save_path, resObj
    
  • 识别效果
    在这里插入图片描述

模拟请求参数,获取返回信息

上面获取到了坐标,但距离成功还差了一步,需要生成 最重要的ac参数

  • 请求参数如下
    在这里插入图片描述
  • 请求代码
def send_verify(sid, aid_dx, x,y,ac):
    headers = {
        'Accept': '*/*',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'Content-type': 'application/x-www-form-urlencoded',
        'Origin': 'https://m.airchina.com.cn',
        'Pragma': 'no-cache',
        'Referer': 'https://m.airchina.com.cn/',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'cross-site',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
        'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="102", "Google Chrome";v="102"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
    }

    data = urlencode({
        'ac': ac,
        'ak': "5f6727ec854786a86cd4c3c171d13499",
        'c': "63490534hEK47XdXUPbCVcFE1MpdpRs4blnVT8w1",
        'uid': '',
        'jsv': '1.5.28.117',
        'sid': sid,
        'aid': aid_dx,
        'x': str(x),
        'y': str(y)
        })
    
    response = requests.post('https://cap.dingxiang-inc.com/api/v1', headers=headers, data=data)
    return response

2.ac 生成

  • ac是由 这个这个js 生成
    https://cdn.dingxiang-inc.com/ctu-group/ctu-greenseer/greenseer.js
  • 通过补环境,传入x、y、sid三个参数,获取ac,相信这个应该是人均都会的水平
请求成功后,大概是这个样子

在这里插入图片描述

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值