滑块 验证

inks / 2023-08-03 / 原文

爬虫方面必须会的

两款 需要还原 底图 轨迹

第一个 pkulaw

import json
import random

from PIL import Image
from io import BytesIO
from base64 import b64decode
from ddddocr import DdddOcr
import time

import requests

def generate_track(distance):
    """
    生成滑块的轨迹
    :param distance: 滑块需要滑动的距离
    :return: 滑块的轨迹列表
    """
    tracks = []  # 滑块的轨迹列表
    current = 0  # 当前滑动距离
    mid = distance * 3 / 4  # 拖动距离的3/4作为中间位置
    t = 0.2  # 模拟人的动作间隔时间

    v = 0  # 初始速度
    while current < distance:
        if current < mid:
            a = random.uniform(2, 3)  # 加速度在2-3之间随机取值
        else:
            a = -random.uniform(2, 3)  # 加速度在-2到-3之间随机取值

        v0 = v  # 初始速度
        v = v0 + a * t  # 当前速度
        move = v0 * t + 0.5 * a * t * t  # 当前位移

        current += move
        tracks.append(round(move))
    vv = []
    det = 0
    for i in tracks:
        det += i
        t = round(time.time() * 1000)
        vv.append("{},{}".format(det, t))
        time.sleep(0.005)

    return '|'.join(vv)
class Slider():
    def __init__(self):
        self.dd = DdddOcr(det=False, ocr=False)
        self.req = requests.Session()
        self.req.headers = {
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
            'Connection': 'close',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Origin': 'https://www.pkulaw.com',
            'Referer': 'https://www.pkulaw.com/',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.188',
            'X-Requested-With': 'XMLHttpRequest',
            'sec-ch-ua': '"Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"Windows"',
        }

    def downimg(self):
        data = 'act=getcode&spec=300*200'

        response = self.req.post('https://www.pkulaw.com/VerificationCode/GetVerifiCodeResult',
                                 data=data).json()
        resjson = json.loads(response)
        y = resjson['y']
        arr = resjson['array']
        small = resjson['small']
        with open('target.jpg', 'wb') as fp:
            fp.write(b64decode(small.split(',')[1]))
        normal = resjson['normal']
        self.resimg(arr.split(','), b64decode(normal.split(',')[1]))

    def resimg(self, arr, imgtxt):
        # 还原 图片
        img = Image.open(BytesIO(imgtxt))
        newimg = Image.new("RGB", img.size)
        u = 30
        f = 100
        for i in range(len(arr)):
            num = int(arr[i])
            x = int((i - 10) * u if i > 9 else i * u)
            y = 100 if i > 9 else 0
            #         开始截取
            cort = img.crop((x, y, x + u, y + f))
            newx = (num - 10) * u if num > 9 else num * u
            newy = 100 if num > 9 else 0
            newimg.paste(cort, (newx, newy))
        newimg.save('bg.jpg')

    def detslice(self):
        with open('bg.jpg', 'rb') as fp:
            bg = fp.read()
        with open('target.jpg', 'rb') as fp:
            tar = fp.read()
        return (self.dd.slide_match(tar, bg, simple_target=True))['target']

    def postslider(self, x):
        # 发送请求
        data = {
            'act': 'check',
            'point': '{}'.format(x),
            'timespan': '1625',
            'datelist': generate_track(x)
        }
        print(generate_track(x))
        response = self.req.post(
            'https://www.pkulaw.com/VerificationCode/GetVerifiCodeResult',
            data=data,
        )
        print(response.json())



    def main(self):
        self.downimg()
        x = self.detslice()
        self.postslider(x[0])


if __name__ == '__main__':
    x = Slider()
    x.main()
View Code

效果:

 

第二个极验 明天弄