标签 模拟 下的文章

方式一

const dragAndDrop = async (elem, startX, startY, distance) => {
    // 初始化鼠标事件
    const dispatchMouseEvent = (type, x, y) => {
        const event = new MouseEvent(type, {
            view: window,
            bubbles: true,
            cancelable: true,
            clientX: Math.floor(x),
            clientY: Math.floor(y),
            screenX: Math.floor(x + window.screenX),
            screenY: Math.floor(y + window.screenY),
            button: 0,
            // 当是 mousedown 或 mousemove 时,保持左键按下状态
            buttons: type === 'mouseup' ? 0 : 1,
        });
        elem.dispatchEvent(event);
    };

    // 贝塞尔曲线运动参数
    const duration = 800 + Math.random() * 400; // 随机持续时间
    const startTime = performance.now();
    const humanizeFactor = 0.3; // 人类操作随机因子

    // 触发初始按下事件
    dispatchMouseEvent('mousedown', startX, startY);

    // 使用requestAnimationFrame实现平滑动画
    return new Promise(resolve => {
        const animate = (currentTime) => {
            const elapsed = currentTime - startTime;
            const progress = Math.min(elapsed / duration, 1);

            // 应用缓动函数(三次贝塞尔曲线)
            const easedProgress = Math.sin(progress * Math.PI / 2);

            // 添加人类操作随机扰动
            const randomOffset = Math.random() * humanizeFactor * distance;
            const currentX = startX + (distance * easedProgress) + randomOffset;
            const currentY = startY + Math.sin(progress * Math.PI) * 5; // 自然Y轴波动

            dispatchMouseEvent('mousemove', currentX, currentY);

            if (progress < 1) {
                requestAnimationFrame(animate);
            } else {
                // 结束操作
                dispatchMouseEvent('mouseup', currentX, currentY);
                resolve();
            }
        };

        requestAnimationFrame(animate);
    });
};

// 优化后的启动函数
const simulateHorizontalDrag = async (slide, distance) => {
    const elem = document.querySelector(slide);
    if (!elem) {
        logger.error('selector:%s not found', slide);
        return;
    }

    const rect = elem.getBoundingClientRect();
    const startX = rect.left + rect.width * 0.3 + Math.random() * rect.width * 0.4;
    const startY = rect.top + rect.height * 0.3 + Math.random() * rect.height * 0.4;

    await dragAndDrop(elem, startX, startY, distance);
};

方式二

function dragandDrop(id, clientX, clientY, distance) {
    const elem = document.querySelector(id);
    let k = 0;
    iME(elem, "mousedown", 0, 0, clientX, clientY);
    const interval = setInterval(function () {
        k++;
        iME(elem, "mousemove", clientX + k, clientY, clientX + k, clientY);

        if (k >= distance) {
            clearInterval(interval);
            iME(elem, "mouseup", clientX + k, clientY, clientX + k, clientY);
        }
    }, 8);

    function iME(obj, event, screenXArg, screenYArg, clientXArg, clientYArg) {
        const mousemove = document.createEvent("MouseEvent");
        mousemove.initMouseEvent(event, true, true, window, 0,
            screenXArg, screenYArg, clientXArg, clientYArg, 0, 0, 0, 0, 0, null);
        obj.dispatchEvent(mousemove);
    }
}

function simulateHorizontalDrag(slide, distance) {
    const obj = document.querySelector(slide);
    obj.target = '_self';
    const _owh = obj.getBoundingClientRect();
    let _ox = _owh.width / 2, _oh = _owh.height / 2;
    _ox = Math.floor(Math.random() * _ox + 60);
    _oh = Math.floor(Math.random() * _oh + 60);
    _ox = _ox + _owh.x;
    _oh = _oh + _owh.y;
    dragandDrop(slide, _ox, _oh, distance);
}

browser = p.chromium.launch(headless=False)  # 禁用无头模式以显示浏览器窗口
context = browser.new_context(
    user_agent=None,
    viewport={"width": 1500, "height": 800},
)

改为

browser = p.chromium.launch(headless=False)  # 禁用无头模式以显示浏览器窗口
context = browser.new_context(
    no_viewport=True,  # 使用浏览器的默认视口
    user_agent=None,  # 使用浏览器的默认 User-Agent
)

async function inputText(input, text) {
  // 手动触发 input 和 change 事件
  for (let event of ['click', 'focus', 'text', 'input', 'change', 'blur']){
  if (event === 'text'){
    input.value = text;
  }else{
        input.dispatchEvent(new Event(event, { bubbles: true }));

  }
  await sleep(600)
  }
}

方式1

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function simulateTextInput(inputBox, text) {
    let range = document.createRange();
    range.selectNodeContents(inputBox);
    let sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);

    await sleep(500)

    let inputEvent = new InputEvent('input', {
        bubbles: true,
        cancelable: true,
        inputType: 'insertText',
        data: text
    });

    inputBox.textContent = text;
    inputBox.dispatchEvent(inputEvent);
}

box = document.querySelector('#main .copyable-area [contenteditable="true"][role="textbox"]')
simulateTextInput(box, "😇")

方式2

let text = document.querySelector('div textarea')
    let pasteEvent = new ClipboardEvent('paste', {
        dataType: 'text/plain',
        data: imgs.join('\n')
    });

    let event = new Event('input', {
        bubbles: true,
        cancelable: true,
    });

// 模拟设置粘贴的内容
    text.value = 'something';

// 触发粘贴事件
    text.dispatchEvent(event);

方式3

const e = new InputEvent("input", {
                bubbles: true,
                cancelable: true
            });
            ele.dispatchEvent(e);
            const ee = new KeyboardEvent("keydown", {
                altKey: false,
                bubbles: true,
                cancelable: true,
                key: 'Enter',
                code: 'Enter',
                keyCode: 13,
                repeat: false
            });
            ele.dispatchEvent(ee);

终极

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function fillData(input, value) {
    let events = ['click', 'focus', 'setVal', 'input', 'change', 'blur'];
    for (let event of events) {
        if (event === 'setVal') {
            if (input.tagName.toLowerCase() === 'input') {
                input.setAttribute('value', value)
            } else {
                //text
                input.textContent = value
            }
        } else {
            console.log(`fill value query: ${input} value: ${value} event: ${event}`,);
            let eventObj = new Event(event, {
                bubbles: true,
                cancelable: true,
            })
            input.dispatchEvent(eventObj);
            await sleep(400)
        }
    }
}