Великий артефакт фронтенд-инженеров — кукольник

Puppeteer
Великий артефакт фронтенд-инженеров — кукольник

Подпишитесь на официальный аккаунт «Kite Handler», ответьте «Данные», чтобы получить данные 500G (все «руки»), и профессиональные коммуникационные группы ждут, когда вы соберетесь вместе. (Ха-ха)

В этой статье в основном описывается артефакт кукольника, опубликованный Google и постоянно поддерживаемый.Изучив эту статью, вы поймете его основное использование и общие функции.

1. Введение в Кукольника

Puppeteer – это библиотека Node, предоставляющая высокоуровневый API для управления Chromium или Chrome через протокол DevTools. Используя Puppeteer, вы можете получать узлы DOM страницы, сетевые запросы и ответы, программно управлять поведением страницы, выполнять мониторинг и оптимизацию производительности страницы, а также получить страницы, скриншоты и PDF-файлы и т. д., вы можете использовать этот артефакт для управления браузером Chrome, чтобы выполнять различные трюки.

Во-вторых, основная структура Puppeteer

Структура Puppeteer также отражает структуру браузера, и его основная структура выглядит следующим образом:

  1. Браузер: это экземпляр браузера, который может владеть контекстом браузера, создавая объект браузера через puppeteer.launch или puppeteer.connect.
  2. BrowserContext: этот экземпляр определяет контекст браузера, который может иметь несколько страниц. При создании экземпляра браузера по умолчанию создается контекст браузера (который нельзя закрыть). Кроме того, анонимный контекст браузера может быть создан с помощью browser.createIncognitoBrowserContext( ) (не будет делиться файлами cookie/кешем с другими контекстами браузера).
  3. Страница: содержит как минимум один основной фрейм, кроме основного фрейма могут быть и другие фреймы, например iframe.
  4. Фрейм: кадр на странице.В каждый момент времени страница предоставляет сведения о текущем кадре с помощью методов page.mainFrame() и frame.childFrames(). Хотя бы для одного контекста выполнения в этом фрейме
  5. ExecutionCONtext: представляет контекст выполнения JavaScript.
  6. Worker: имеет единый контекст выполнения для удобного взаимодействия с WebWorkers.

3. Основное использование и общие функции

Артефакт относительно прост в использовании в целом, поэтому давайте начнем наше путешествие по использованию.

3.1 Запустить браузер

Основная функция заключается в асинхронном вызове функции puppeteer.launch() для создания экземпляра браузера в соответствии с соответствующими параметрами конфигурации.

const path = require('path');
const puppeteer = require('puppeteer');

const chromiumPath = path.join(__dirname, '../', 'chromium/chromium/chrome.exe');

async function main() {
    // 启动chrome浏览器
    const browser = await puppeteer.launch({
        // 指定该浏览器的路径
        executablePath: chromiumPath,
        // 是否为无头浏览器模式,默认为无头浏览器模式
        headless: false
    });
}

main();

3.2 Посетите страницу

Чтобы получить доступ к странице, вам сначала нужно создать контекст браузера, затем создать новую страницу на основе контекста и, наконец, указать URL-адрес для доступа.

async function main() {
    // 启动chrome浏览器
    // ……

    // 在一个默认的浏览器上下文中被创建一个新页面
    const page1 = await browser.newPage();

    // 空白页刚问该指定网址
    await page1.goto('https://51yangsheng.com');

    // 创建一个匿名的浏览器上下文
    const browserContext = await browser.createIncognitoBrowserContext();
    // 在该上下文中创建一个新页面
    const page2 = await browserContext.newPage();
    page2.goto('https://www.baidu.com');
}

main();

3.3 Моделирование устройства

Часто требуются результаты просмотра различных типов моделей.В настоящее время имитация устройства может использоваться для имитации результатов просмотра браузера устройства iPhone X.

async function main() {
    // 启动浏览器

    // 设备模拟:模拟一个iPhone X
    // user agent
    await page1.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1')
    // 视口(viewport)模拟
    await page1.setViewport({
        width: 375,
        height: 812
    });
    
    // 访问某页面
}

main();

3.4 Получить узел DOM

Есть два способа получить DOM-узлы: один — напрямую вызвать нативную функцию страницы, а другой — получить ее, выполнив код js.

async function main() {
    // 启动chrome浏览器
    const browser = await puppeteer.launch({
        // 指定该浏览器的路径
        executablePath: chromiumPath,
        // 是否为无头浏览器模式,默认为无头浏览器模式
        headless: false
    });

    // 在一个默认的浏览器上下文中被创建一个新页面
    const page1 = await browser.newPage();

    // 空白页刚问该指定网址
    await page1.goto('https://www.baidu.com');

    // 等待title节点出现
    await page1.waitForSelector('title');

    // 用page自带的方法获取节点
    const titleDomText1 = await page1.$eval('title', el => el.innerText);
    console.log(titleDomText1);// 百度一下

    // 用js获取节点
    const titleDomText2 = await page1.evaluate(() => {
        const titleDom = document.querySelector('title');
        return titleDom.innerText;
    });
    console.log(titleDomText2);
}

main();

3.5 Прослушивание запросов и ответов

Давайте проследим за запросом и ответом js-скрипта в Baidu.Событие запроса должно отслеживать запрос, а событие ответа — отслеживать ответ.

async function main() {
    // 启动chrome浏览器
    const browser = await puppeteer.launch({
        // 指定该浏览器的路径
        executablePath: chromiumPath,
        // 是否为无头浏览器模式,默认为无头浏览器模式
        headless: false
    });

    // 在一个默认的浏览器上下文中被创建一个新页面
    const page1 = await browser.newPage();

    page1.on('request', request => {
        if (request.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') {
            console.log(request.resourceType());
            console.log(request.method());
            console.log(request.headers());
        }
    });

    page1.on('response', response => {
        if (response.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') {
            console.log(response.status());
            console.log(response.headers());
        }
    })

    // 空白页刚问该指定网址
    await page1.goto('https://www.baidu.com');
}

main();

3.6 Перехват запроса

По умолчанию событие запроса имеет атрибуты только для чтения и не может перехватить запрос.Если вы хотите перехватить запрос, вам нужно запустить перехватчик запроса через page.setRequestInterception(value), а затем использовать request.abort, request Методы .continue и request.respond для определения запрошенного следующего действия.

async function main() {
    // 启动chrome浏览器
    const browser = await puppeteer.launch({
        // 指定该浏览器的路径
        executablePath: chromiumPath,
        // 是否为无头浏览器模式,默认为无头浏览器模式
        headless: false
    });

    // 在一个默认的浏览器上下文中被创建一个新页面
    const page1 = await browser.newPage();

    // 拦截请求开启
    await page1.setRequestInterception(true);// true开启,false关闭
    page1.on('request', request => {
        if (request.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') {
            // 终止该请求
            request.abort();
            console.log('该请求被终止!!!');
        }
        else {
            // 继续该请求
            request.continue();
        }
    });

    // 空白页刚问该指定网址
    await page1.goto('https://www.baidu.com');
}

main();

3.7 Скриншоты

Снимок экрана — очень полезная функция, вы можете сохранить снимок экрана, сделав снимок экрана, что удобно для последующего устранения неполадок. (Внимание: Скриншоты делайте в безголовом режиме, иначе могут быть проблемы со скриншотами)

async function main() {
	// 启动浏览器,访问页面的操作
    
    // 截屏操作,使用Page.screenshot函数
    // 截取整个页面:Page.screenshot函数默认截取整个页面,加上fullPage参数就是全屏截取
    await page1.screenshot({
        path: '../imgs/fullScreen.png',
        fullPage: true
    });

    // 截取屏幕中一个区域的内容
    await page1.screenshot({
        path: '../imgs/partScreen.jpg',
        type: 'jpeg',
        quality: 80,
        clip: {
            x: 0,
            y: 0,
            width: 375,
            height: 300
        }
    });

    browser.close();
}

main();

3.8 Создать PDF-файл

Помимо использования снимков для сохранения моментального снимка, вы также можете использовать pdf для сохранения моментального снимка.

async function main() {
	// 启动浏览器,访问页面的操作
    
    // 根据网页内容生成pdf文件,使用Page.pdf——注意:必须在无头模式下才可以调用
    await page1.pdf({
        path: '../pdf/baidu.pdf'
    });

    browser.close();
}

main();

1. Если вы считаете, что эта статья неплохая, поделитесь ею и поставьте лайк, чтобы ее увидело больше людей.

2. Подпишитесь на официального владельца учетной записи, получайте учебные материалы (внешние «многорукие» материалы) и регулярно публикуйте для вас оригинальные и подробные полезные статьи.