Yahor Vaziyanau
Профессиональный формошлеп / JS разработчик / Bug Janitor.
Version 42.0
Software Engineer в
iTechArt Group.
Профессиональный формошлёп.
JavaScript-разработчик с
958-дневным стажем.
Это браузер без графического интерфейса.
Также:
Approved by
Approved by
PhantomJS — это заскриптованный безголовый WebKit с JavaScript API.
У него есть быстрая и нативная поддержка различных веб стандартов: DOM handling, CSS selector, JSON, Canvas, и SVG.
Поддерживаемые языки:
JavaScript, Python, Ruby, Java, C#, Haskell, Objective-C, Perl, PHP, R (через Selenium).
Статус: RIP.
Nightmare — это высокоуровневая библиотека для работы с автоматизацией в браузере, созданная как более простая версия PhatomJS. Работает на Electron.
Поддерживаемые языки:
JavaScript.
Статус: Жив. Здоров. Развивается.
SlimerJS похож на PhantomJs, только использует движок Gecko (Mozilla Firefox) вместо WebKit .
(И это еще он не по-настоящему безголовый).
Поддерживаемые языки:
JavaScript
Статус: Сейчас Жив и Здоров. По слухам скоро RIP.
Итак.
Ты используешь
Internet Explorer.
Поддерживаемые языки:
JavaScript
Статус: RIP.
Безголовый Internet Explorer, который использует .NET WebBrowser Class & JavaScript API с движком V8 на борту.
Активируется через флаг
--headless либо с помощью Node.JS или C++ библиотек.
Поддерживаемые языки:
JavaScript, C++.
Статус: Жив. Здоров. Развивается.
chrome --headless --disable-gpu --screenshot https://www.chromestatus.com/
# Size of a standard letterhead.
chrome --headless --disable-gpu --screenshot --window-size=1280,1696 https://www.chromestatus.com/
# Nexus 5x
chrome --headless --disable-gpu --screenshot --window-size=412,732 https://www.chromestatus.com/
Статус: Жив. Здоров. Развивается.
Принцип работы такой же, как и у Headless Chrome.
Активируется пока только через флаг --headless либо через Selenium.
Поддерживаемые языки:
JavaScript, Java, Python (через Selenium).
/path/to/firefox -headless -screenshot https://developer.mozilla.com
/path/to/firefox -screenshot test.jpg https://developer.mozilla.com --window-size=800,1000
Headless режим отсутствует.
Есть вариант использования через веб драйвер chromedp.
Статус: NaN.
Поддерживаемые языки:
NaN.
Поддерживаемые языки:
NaN.
Headless режим отсутствует.
Есть вариант использования через веб драйвер chromedp.
Пока релизнулся
Microsoft Edge DevTools Protocol.
Статус: NaN.
Puppeteer (Кукловод) — это библиотека для Node.JS которая предоставляет высокоуровневый API для контроля над безголовым хромом или хромиумом через DevTools Protocol.
Его также можно сконфигурировать для использование в full режиме (не безголовый режим).
npm i puppeteer
или yarn add puppeteer
npm i puppeteer-core
или yarn add puppeteer-core
Chrome DevTools Protocol
Chromium
Кукловод
Скрипты
для Chrome
Firefox DevTools Protocol (в разработке)
Gecko
Кукловод
Скрипты
для Firefox (alpha)
const puppeteer = require('puppeteer');
const fs = require('fs');
const URL = 'https://github.com/';
(async () => {
// NOTE: Puppeteer sets an initial page size to 800px x 600px, which defines the screenshot size.
// The page size can be customized with Page.setViewport()
const dir = './screens';
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
const browser = await puppeteer.launch({
headless: true,
ignoreHTTPSErrors: true,
});
const page = await browser.newPage();
page.setViewport({
width: 1920,
height: 1080,
})
await page.goto(URL, {
waitUntil: ['networkidle0', 'domcontentloaded'],
// timeout: 30000,
});
await page.screenshot({
path: 'screens/example.png',
})
await page.screenshot({
path: 'screens/fullpage.png',
fullPage: true,
})
await browser.close();
})();
const puppeteer = require('puppeteer');
const fs = require('fs');
const URL = 'https://github.com/';
// NOTE: u can't add script tag init :) yet
const buildTemplate = (type) => {
// If you do not need customize =>
// https://github.com/GoogleChrome/puppeteer/blob/v1.14.0/docs/api.md#pagepdfoptions
// Since version 1.2+ you can use footerTemplate & headerTemplate API
return `
<div style="font-size: 10px; color: red;">
<span>${ type === 'header' ? 'HEADER' : 'FOOTER'}</span>
<span class="date"></span> |
<span class="title"></span> |
<span class="url"></span> |
<span class="pageNumber"></span> /
<span class="totalPages"></span>
</div>
`;
}
(async () => {
const dir = './pdf';
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
const browser = await puppeteer.launch({
headless: true,
ignoreHTTPSErrors: true,
});
const page = await browser.newPage();
await page.goto(URL, {
waitUntil: ['networkidle0', 'domcontentloaded'],
// timeout: 30000,
});
await page.pdf({
path: 'pdf/document.pdf',
displayHeaderFooter: true,
headerTemplate: buildTemplate('header'), // new one
footerTemplate: buildTemplate('footer'), // new one
printBackground: true,
landscape: false,
// pageRanges: '1-2',
format: 'A4',
margin: {
top: 100,
right: 40,
bottom: 100,
left: 40,
},
})
await browser.close();
})();
// ...
// Enable both JavaScript and CSS coverage
await Promise.all([
page.coverage.startJSCoverage(),
page.coverage.startCSSCoverage()
]);
await page.tracing.start({path: 'trace.json'});
await page.goto(`${URL}/books/allbooks/`, {
waitUntil: ['networkidle0', 'domcontentloaded'],
// timeout: 30000,
});
// Disable both JavaScript and CSS coverage
const [jsCoverage, cssCoverage] = await Promise.all([
page.coverage.stopJSCoverage(),
page.coverage.stopCSSCoverage(),
]);
let totalJSBytes = 0;
let usedJSBytes = 0;
for (const entry of jsCoverage) {
totalJSBytes += entry.text.length;
for (const range of entry.ranges) {
usedJSBytes += range.end - range.start - 1;
}
}
console.log(`JS used (bytes): ${Math.round(usedJSBytes / totalJSBytes * 100)}%`);
let totalCSSBytes = 0;
let usedCSSBytes = 0;
for (const entry of cssCoverage) {
totalCSSBytes += entry.text.length;
for (const range of entry.ranges) {
usedCSSBytes += range.end - range.start - 1;
}
}
console.log(`CSS used (bytes): ${Math.round(usedCSSBytes / totalCSSBytes * 100)}%`);
// how it was year ago
// https://michaljanaszek.com/blog/test-website-performance-with-puppeteer
// for more use CDPSession => client.send(Performance API)
const metrics = await page.metrics();
console.log(`Page metrics: \n`, metrics);
await page.tracing.stop();
// ...
const parse = require('./parse');
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
const url = `https://www.mann-ivanov-ferber.ru`;
async function launchChromeAndRunLighthouse(url, opts, config = null) {
return chromeLauncher.launch({ chromeFlags: opts.chromeFlags }).then((chrome) => {
opts.port = chrome.port;
return lighthouse(url, opts, config).then((results) => {
// use results.lhr for the JS-consumeable output
// https://github.com/GoogleChrome/lighthouse/blob/master/types/lhr.d.ts
// use results.report for the HTML/JSON/CSV output as a string
// use results.artifacts for the trace/screenshots/other specific case you need (rarer)
return chrome.kill().then(() => results);
});
});
}
const opts = {
chromeFlags: ['--show-paint-rects'],
};
const runLH = async function() {
try {
const results = await launchChromeAndRunLighthouse(url, opts);
const urlArtifactsRes = await parse.getMainArtifacts(results)
const urlBasicScores = await parse.getBasicsScores(results)
// console.log('*** Runtime info ***')
// console.log(urlArtifactsRes.toString())
console.log('*** Basic scores ***')
console.log(urlBasicScores.toString())
} catch (err) {
console.log(err);
}
};
runLH()
Эй, гугл! А есть еще примеры?
Да, проходи.
НО
By Yahor Vaziyanau
Что делать, если нам нужно сделать из веб-страницы pdf-документ или скриншот? Или если вдруг возникла необходимость написать UI-тесты и посмотреть статистику использования CSS-селекторов и вызова JS-функций? Правильно, использовать PhantomJS. Ой. Погодите, на дворе — 2019 год. Настало время Puppeteer — Node API для «безголового» Chrome от Google!