Протокол Puppeteer / Chrome DevTools: есть ли способ запустить стандартный зум (не без головы)

Я запускаю кукловод с отключенным безголовым режимом, чтобы автоматизировать и удаленно управлять видимым браузером Chromium на другом компьютере.

Есть ли способ запустить или эмулировать масштабирование в браузере, как в меню пользовательского интерфейса или ctrl +/crtl - команды?

Внедрение CSS или использование различных задокументированных команд масштабирования не полностью воспроизводит это, как, например, элементы, определенные с помощью vh/vw единицы не настраиваются.


Мое текущее решение

Использование масштаба видового экрана в Emulation.setDeviceMetricsOverride хорошо работает для уменьшения масштаба, но, похоже, он изменяет размер растра страницы, а не отображает целевой размер, что приводит к размытому тексту при увеличении.

Регулировка размера области просмотра и использование Emulation.setPageScaleFactor хорошо работает для увеличения, однако pageScaleFactor меньше 1 в моем тестировании игнорируется.

Проблема с обоими этими решениями заключается в том, что они требуют заранее знать ширину / высоту окна браузера и полагаются на то, что они не меняются, а не на гибкое окно просмотра. Я также не уверен, каких еще функций стандартного масштабирования браузера мне не хватает.

Мой код для масштабирования теперь:


async applyFrameZoom(page, zoom) {
    // page is a puppeteer.Page instance
    // zoom is an integer percentage

    const session = await page.target().createCDPSession();

    let window = await session.send('Browser.getWindowForTarget', {
        targetId: page.target()._targetId
    });

    let width = window.bounds.width;
    let height = window.bounds.height;

    if (!zoom || zoom === 100) {
        // Unset any zoom
        await session.send('Emulation.clearDeviceMetricsOverride');
        await session.send('Emulation.resetPageScaleFactor');
    } else if (zoom > 100) {
        // Unset other zooming method
        await session.send('Emulation.clearDeviceMetricsOverride');

        // Zoom in by reducing size then adjusting page scale (unable to zoom out using this method)
        await page.setViewport({
            width: Math.round(width / (zoom / 100)),
            height: Math.round(height / (zoom / 100))
        });

        await session.send('Emulation.setPageScaleFactor', {
            pageScaleFactor: (zoom / 100)
        });

        await session.send('Emulation.setVisibleSize', {
            width: width,
            height: height
        });
    } else {
        // Unset other zooming method
        await session.send('Emulation.resetPageScaleFactor');

        // Zoom out by emulating a scaled device (makes text blurry when zooming in with this method)
        await session.send('Emulation.setDeviceMetricsOverride', {
            width: Math.round(width / (zoom / 100)),
            height: Math.round(height / (zoom / 100)),
            mobile: false,
            deviceScaleFactor: 1,
            dontSetVisibleSize: true,
            viewport: {
                x: 0,
                y: 0,
                width: width,
                height: height,
                scale: (zoom / 100)
            }
        });
    }

    await this.frame.waitForSelector('html');
    this.frame.evaluate(function () {
        window.dispatchEvent(new Event('resize'));
    });
}

Есть лучший способ это сделать?

2 ответа

Я просто использую Javascript, чтобы увеличить/уменьшить масштаб.

      await page.evaluate(() => document.body.style.zoom = 0.5  );

Это работает хорошо для меня.

В --force-device-scale-factor Параметр командной строки, похоже, работает для масштабирования всего пользовательского интерфейса Chrome, как для увеличения, так и для уменьшения.

Передаем это в хром с кукловодом:

      puppeteer.launch({
    args: ["--force-device-scale-factor=0.5"],
    headless: false,
})

(Протестировано с хромом 78 / кукловод 1.20.0)


Но если вам нужно увеличить масштаб без перезапуска Chrome или вы не хотите масштабировать весь пользовательский интерфейс, на самом деле есть способ запустить собственное масштабирование Chrome с помощью кукловода.

Я создал репозиторий, демонстрирующий это здесь. Он работает путем обхода расширения chrome, у которого есть доступ к API chrome.tabs.setZoom.

chrome-extension/manifest.json:

      {
    "name": "my-extension-name",
    "description": "A minimal chrome extension to help puppeteer with zooming",
    "version": "1.0",
    "manifest_version": 2,
    "background": {
        "scripts": ["background.js"],
        "persistent": false
    },
    "permissions": []
}

chrome-extension/background.js:

      function setZoom(tabId, zoomFactor) {
    chrome.tabs.setZoom(tabId, zoomFactor)
}

main.js:

      const puppeteer = require('puppeteer');

(async () => {
    const extensionPath = require('path').join(__dirname, 'chrome-extension');
    const extensionName = 'my-extension-name';

    const browser = await puppeteer.launch({
        args: [
            `--disable-extensions-except=${extensionPath}`,
            `--load-extension=${extensionPath}`
        ],
        headless: false,
    });
    const page = await browser.newPage();
    await page.goto('https://google.com');
    
    // get the background page of the extension
    const targets = await browser.targets();
    const extenstionPageTarget = targets.find(
        (target) => target._targetInfo.title === extensionName
    );
    const extensionPage = await extenstionPageTarget.page();

    // do the zooming by invoking setZoom of background.js
    const zoomFactor = 0.5
    await extensionPage.evaluate((zoomFactor) => {
        // a tabId of undefined defaults to the currently active tab
        const tabId = undefined;
        setZoom(tabId, zoomFactor);
    }, zoomFactor);
})();

Я не нашел способа получить tabIdстраницы с помощью кукловода, хотя это, вероятно, снова возможно через расширение. Но вышеперечисленное подойдет, если страница, которую вы хотите увеличить, является активной в данный момент.

Обратите внимание, что загрузка расширений Chrome в настоящее время не работает в режиме без заголовка , но, к счастью, в вашем случае это не проблема.

Другие вопросы по тегам