В конце этой статьи мы узнаем, как

  1. Внедрить пользовательские функции Javascript в контекст другой страницы.
  2. Взаимодействуйте с формами, чтобы автоматизировать работу.
  3. Делайте скриншоты определенных элементов на странице
  4. Использование событий клавиатуры / мыши для ввода / нажатия выбранных элементов.
  5. Снимать скриншоты
  6. Выбор элементов из DOM.
  7. Доступ к файлам cookie

Вступление

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

В этой статье мы рассмотрим недавно запущенный Google Chrome node api Puppeteer от команды разработчиков Google. Наряду с кукольником недавно были выпущены некоторые другие, включая Chromeless, Chrominator, Chromy, Navalia, Lambdium, nightmare js (который похож на Puppeteer, но использует электрон за кулисами, в то время как Puppeteer построен исключительно на хроме) и старые добрые фантомы, которые предоставляет надежный кроссбраузерный API для тестирования.

О кукольнике

Puppeteer - это библиотека Node, которая предоставляет высокоуровневый API для управления Chrome без головы по« протоколу devtools . Его также можно настроить для использования в полной версии (или без нее) Chrome », - говорит команда разработчиков Google.

Кукловода можно использовать для

  • Автоматизируйте визуальное тестирование.
  • Создание изображений / снимков экрана в формате pdf веб-сайтов без открытия браузера.
  • Отправка формы / моделирование использования браузера
  • Парсинг веб-сайтов
  • или запечатлеть временную шкалу

и многое другое.

Давайте начнем с основного использования кукловода.

Вы также можете попробовать это на новой игровой площадке кукловода https://try-puppeteer.appspot.com/

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

На машине Ubuntu

sudo apt-get update

Установка узла v8.4.0 из nodeource. Найдите свой на https://github.com/nodesource/distributions

# This installs nodejs on ubuntu based system
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

вместе с этим вам тоже нужно иметь это

gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget

На Ubuntu

sudo apt-get install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wgetsudo apt-get install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget

Установить npm

sudo apt-get install npm

Теперь в ваш рабочий каталог запустите

npm init
npm -i puppeteer

и тебе хорошо идти. Выполнив указанную выше команду, он устанавливает последнюю версию Chromium и puppeteer. Помните, что нет необходимости иметь дисплей, потому что это безголовый браузер, который может запускаться на серверах / только в командной строке. Если у вас возникнут какие-либо проблемы, перейдите по этой ссылке для устранения неполадок https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md, и если вы используете ubuntu xenial, никаких проблем не возникает, следуйте мой лидер https://github.com/GoogleChrome/puppeteer/issues/290#issuecomment-324838511

Начиная

Создадим снимок экрана веб-сайта в размерах iPad Pro. (768px * 1024px) (согласно http://screensiz.es/).

После установки puppeteer откройте файл .js, вызовите его файл screenshot.js в папке проекта npm и добавьте в него приведенный ниже код ..

const puppeteer = require('puppeteer');
(async () => {
 const browser = await puppeteer.launch();
 const page = await browser.newPage();
 await page.goto('https://google.com');
 await page.setViewport({width : 768 , height : 1024});
 await page.screenshot({path: 'google.png'});
 browser.close();
})();

теперь запустите скрипт в терминале

node screenshot.js

после успешного запуска кода у вас будет снимок экрана google.com, и с помощью одной строчки кода вы даже сможете сохранить его в формате pdf. Добавьте приведенный ниже код перед browser.close ()

await page.pdf({path: 'google.pdf', format: 'A4'});

Помимо A4, вы можете снимать даже другие размеры Letter, Legal, Tabloid, Ledger, A0, A1, A2, A3, A4, A5. Подробнее об этом здесь

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

Сделать это. Нам нужно будет найти положение и размеры этого элемента. Используя эти детали, мы можем вырезать снимок экрана. В кукольнике вы можете вырезать конкретную область снимка экрана. Подробнее об этом методе API см. Https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagescreenshotoptions

Для этого мы будем использовать метод $ eval из api страницы. он принимает в качестве параметров селектор и функцию, которая должна выполняться в контексте страницы. высота и ширина смещения задают размеры элемента, а offsetTop и offsetLeft задают позицию, необходимую для обрезки области.

Ниже скрипт захватывает боковую панель журнала Smashing.

const puppeteer = require('puppeteer');
(async () => {
 const browser = await puppeteer.launch();
 const page = await browser.newPage();
 await page.goto('https://www.smashingmagazine.com/');
 page.setViewport({width : 1400 , height : 2500})
 const html = await page.$eval('.sn', e => [e.offsetWidth,e.offsetHeight,e.offsetTop,e.offsetLeft] );
 await page.screenshot({path : "clip.png", clip : {x : html[2],y : html[3] , width : html[0] , height : html[1]}});
   browser.close();
})();

Изображение слева - это боковая панель веб-сайта SM. Эти настройки особенно полезны во многих ситуациях. Его можно импровизировать и реализовать по своему желанию.

Теперь перейдем к взаимодействию с формой.

Взаимодействие с веб-страницей / формой

Я считаю, что это самая мощная часть браузеров Headless. Взаимодействие со страницей, как если бы она открыта в браузере.

Сделаем снимок экрана старшего брата https://google.com

Метод скриншота Page api делает эту работу за нас.

const puppeteer = require('puppeteer');
(async () => {
 const browser = await puppeteer.launch();
 const page = await browser.newPage();
 await page.goto('https://google.com');
 await page.screenshot({path : "google.png"});
})();

Контрольная точка №1: Теперь давайте начнем набирать текст, не открывая браузер, как это круто !!!. Перед вводом вы должны сосредоточиться на элементе ввода, как если бы вы использовали браузер. Для этого нам нужно сосредоточиться на элементе ввода. Перед этим давайте найдем элемент, на котором нужно сосредоточиться

Контрольная точка № 2: щелкните правой кнопкой мыши на панели поиска ввода и выберите элемент проверки. (Чтобы узнать больше об использовании проверки инструментов разработчика, посетите здесь https://developer.chrome.com/devtools). Теперь выберите идентификатор этого элемента, кстати, его lst-ib, и я не знаю, что означает lst-ib в любом случае, page.click (), page.type (), page.tap () - это лишь немногие из взаимодействий. функции обработки среди многих других. Сфокусируйтесь на элементе, щелкнув по нему с помощью page.click (element), а затем начните вводить с помощью page.type (передать то, что нужно ввести), а затем сделайте снимок экрана.

const puppeteer = require('puppeteer');
(async () => {
   const browser = await puppeteer.launch();
   const page = await browser.newPage();
   await page.goto('https://google.com');
   await page.screenshot({path : "google.png"});
   page.click("#lst-ib");
   page.type("Smashing magazine");
   ## before v0.12.0
   page.click("#lst-ib");
   page.type("Smashing magazine");
   ## after v0.12.0 as per suggestion by https://medium.com/@dan_kim
   page.type("#lst-ib","Smashing magazine");   
   
   await page.screenshot({path : "google1.png"});
   browser.close();
})();

Контрольная точка № 3: Теперь мы должны щелкнуть по отправке или нажать клавишу ввода. Давайте рассмотрим оба способа, и вы узнаете, насколько гибким является API даже для обработки нажатий клавиш.

Теперь, когда мы ввели, давайте нажмем кнопку «Поиск в Google». Поскольку для него не указан идентификатор (проверка элементов), мы должны использовать любые другие селекторы. Вы можете попробовать это в консоли на главной странице Google.

document.querySelectorAll('input[type="submit"]')[0]

дает вам элемент ввода для отправки.

Теперь в кукольнике нам нужно нажать кнопку и дождаться, пока он перейдет в режим навигации, что можно сделать с помощью page.waitForNavigation (); а затем снова сделайте снимок экрана.

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://google.com');
  await page.screenshot({path : "google.png"});
  page.click("#lst-ib");
  page.type("Smashing magazine");
  await page.screenshot({path : "google1.png"});
  page.click('input[type="submit"]');
  // Note although the page has two input[type="submit"] elements it picks up the   first one more about it here.
  await page.waitForNavigation();
  await page.screenshot({path : "google2.png"});
  browser.close();
})();

Теперь попробуем ввести поиск по ключу. После контрольной точки №2 обратите внимание на использование метода down () класс клавиатуры.

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://google.com');
    await page.screenshot({path : "google.png"});
    page.click("#lst-ib"); //Focus on input element
    page.type("Medium top articles");
    await page.screenshot({path : "google1.png"});
    page.keyboard.down('Enter'); // Press enter
    await page.waitForNavigation();
    await page.screenshot({path : "google2.png"});
    browser.close();
})();

До сих пор мы видели, как выбирать элементы с помощью селекторов и кукловода для взаимодействия с полями формы, имитируя события мыши и клавиатуры.

Запуск пользовательских функций javascript внутри контекста страниц.

Давайте выполним функцию внутри контекста страницы и изменим логотип Google на логотип Smash Magazine.

Путем проверки логотипа Google на сайте google.com с идентификатором "hplogo". Мы будем использовать функцию eval API страницы кукловода, которая принимает селектор и функцию вместе со своими аргументами в качестве аргументов, оценивает переданную функцию в контексте страницы в данном случае google.com.

const puppeteer = require('puppeteer');
const sleep = require('sleep'); 
// Not necessary, becuase we are loading the smahingmagazine's logo it takes time to load the image. Hence if we wait its for a while the image will be loaded and then a screenshot can be taken.
(async () => {
 const browser = await puppeteer.launch();
 const page = await browser.newPage();
 await page.goto('https://google.com');
 const html = await page.$eval('#hplogo', e => e.children[0].innerHTML = '<img src="https://media-mediatemple.netdna-ssl.com/wp-content/themes/smashing-magazine/assets/images/logo.svg">');
 sleep.sleep(2); // wait for 2 seconds so that the SM logo loads completely.
await page.screenshot({path : "jack.png"}); //capture the screenshot
 browser.close();
})();

Разное

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

const browser = await.puppeteer.launch({headless : false});

Это запустит сценарий, а также запустит браузер.

Позволяет получить доступ к файлам cookie, хранящимся на google.com

Класс page.cookies предоставит вам доступ к файлам cookie страницы.

(async () => {
 const browser = await puppeteer.launch();
 const page = await browser.newPage();
 await page.goto('https://google.com');
 var c = await page.cookies();
 console.log(c); // outputs the cookie
 browser.close();
})();

Вывод на мой ящик.

[ 
 { 
  name: '1P_JAR',
  value: '2017-9-12-13',
  domain: '.google.co.in',
  path: '/',
  expires: 1505827402,
  size: 18,
  httpOnly: false,
  secure: false,
  session: false 
 },
 {
  name: 'NID',
  value: 'I have erased the cookies value. Just incase',
  domain: '.google.co.in',
  path: '/',
  expires: 1521033802.002931,
  size: 135,
  httpOnly: true,
  secure: false,
  session: false
 }
]

В последнее время в космосе появилось много безголовых браузеров, таких как Chromeless: https://github.com/graphcool/chromeless, Chrominator: https://github.com/jesg/chrominator. и многие другие".

Полезные ссылки

Https://github.com/GoogleChrome/puppeteer/