Gözetimsiz Chrome'u Kullanmaya Başlama

Özet

Gözetimsiz Chrome, Chrome 59 sürümünde kullanıma sunuluyor. Bu, Chrome tarayıcıyı gözetimsiz bir ortamda çalıştırmanın bir yoludur. Sonuç olarak, Chrome'u Chrome olmadan çalıştırmak gerekiyor. Chromium ve Blink oluşturma motoru tarafından sağlanan tüm modern web platformu özelliklerini komut satırına taşır.

Neden yararlı?

Gözetimsiz tarayıcı, görünür bir kullanıcı arayüzü kabuğuna ihtiyaç duymadığınız otomatik test ve sunucu ortamları için mükemmel bir araçtır. Örneğin, gerçek bir web sayfası üzerinde birkaç test yapmak, bu sayfanın PDF biçiminde bir kopyasını oluşturmak veya sadece tarayıcının bir URL'yi nasıl oluşturduğunu incelemek isteyebilirsiniz.

Gözetimsiz Başlatma (KSA)

Gözetimsiz modu kullanmaya başlamanın en kolay yolu, komut satırından Chrome ikili programını açmaktır. Chrome 59 veya sonraki bir sürüm yüklüyse Chrome'u --headless işaretiyle başlatın:

chrome \
--headless \                   # Runs Chrome in headless mode.
--disable-gpu \                # Temporarily needed if running on Windows.
--remote-debugging-port=9222 \
https://www.chromestatus.com   # URL to open. Defaults to about:blank.

chrome, Chrome yüklemenize işaret etmelidir. Kesin konum platformdan platforma değişir. Mac kullandığımdan, yüklediğim her Chrome sürümü için kullanışlı takma adlar oluşturdum.

Chrome'un mevcut ürün kanalındaysanız ve Beta sürümünü alamıyorsanız chrome-canary kullanmanızı öneririz:

alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"
alias chrome-canary="/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary"
alias chromium="/Applications/Chromium.app/Contents/MacOS/Chromium"

Chrome Canary'yi buradan indirin.

Komut satırı özellikleri

Bazı durumlarda, gözetimsiz Chrome'u programatik olarak komut dosyası çalıştırmanız gerekmeyebilir. Sık gerçekleştirilen görevleri gerçekleştirmek için bazı faydalı komut satırı işaretleri vardır.

DOM'yi yazdırma

--dump-dom işareti document.body.innerHTML öğesini stdout'a yazdırır:

    chrome --headless --disable-gpu --dump-dom https://www.chromestatus.com/

PDF oluşturun

--print-to-pdf işareti sayfanın PDF dosyasını oluşturur:

chrome --headless --disable-gpu --print-to-pdf https://www.chromestatus.com/

Ekran görüntüsü alma

Bir sayfanın ekran görüntüsünü almak için --screenshot işaretini kullanın:

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/

--screenshot ile çalıştırıldığında, mevcut çalışma dizininde screenshot.png adlı bir dosya oluşturulur. Tam sayfa ekran görüntüleri arıyorsanız her şey biraz daha karmaşıktır. David Schnurr’un bu konuda harika bir blog yayını var. Otomatik ekran görüntüsü aracı olarak gözetimsiz Chrome'u kullanma bölümüne göz atın.

REPL modu (okuma-eval-yazdırma döngüsü)

--repl işareti, JS ifadelerini doğrudan komut satırından değerlendirebileceğiniz bir modda gözetimsiz çalıştırır:

$ chrome --headless --disable-gpu --repl --crash-dumps-dir=./tmp https://www.chromestatus.com/
[0608/112805.245285:INFO:headless_shell.cc(278)] Type a Javascript expression to evaluate or "quit" to exit.
>>> location.href
{"result":{"type":"string","value":"https://www.chromestatus.com/features"}}
>>> quit
$

Tarayıcı kullanıcı arayüzü olmadan Chrome'daki hata ayıklama işlemleri

Chrome'u --remote-debugging-port=9222 ile çalıştırdığınızda DevTools protokolü etkin olarak bir örnek başlatır. Protokol, Chrome ile iletişim kurmak ve gözetimsiz tarayıcı örneğini yürütmek için kullanılır. Ayrıca Sublime, VS Code ve Node gibi araçlar, bir uygulamada uzaktan hata ayıklamak için de bu yöntemlerden yararlanır. #synergy

Sayfayı görüntülemek için tarayıcı kullanıcı arayüzünüz olmadığından her şeyin çalışıp çalışmadığını kontrol etmek için başka bir tarayıcıda http://localhost:9222 adresine gidin. İncelenemeyen sayfaların bir listesini görürsünüz. Tıklayıp Headless'ın ne oluşturduğunu görebilirsiniz:

Geliştirici Araçları Uzaktan Kumandası
Geliştirici Araçları uzaktan hata ayıklama kullanıcı arayüzü

Buradan, normalde yaptığınız gibi sayfayı incelemek, hata ayıklamak ve ince ayarlar yapmak için Geliştirici Araçları özelliklerini kullanabilirsiniz. Gözetimsiz modeli programatik olarak kullanıyorsanız bu sayfa, aynı zamanda kablodan oluşan ve tarayıcıyla iletişim kuran tüm ham Geliştirici Araçları protokol komutlarını görmek için güçlü bir hata ayıklama aracıdır.

Programlı olarak kullanma (Düğüm)

Kuklacı

Puppeteer, Chrome ekibi tarafından geliştirilen bir düğüm kitaplığıdır. Gözetimsiz (veya tam) Chrome'u kontrol etmek için üst düzey bir API sağlar. Phantom ve NightmareJS gibi diğer otomatik test kitaplıklarına benzer, ancak yalnızca Chrome'un en son sürümleriyle çalışır.

Puppeteer, diğer avantajlarının yanı sıra, kolayca ekran görüntüsü almak, PDF oluşturmak, sayfalarda gezinmek ve bu sayfalar hakkında bilgi getirmek için de kullanılabilir. Tarayıcı testlerini hızlı bir şekilde otomatik hale getirmek istiyorsanız kitaplığı öneririm. Geliştirici Araçları protokolünün karmaşıklıklarını gizler ve Chrome'un hata ayıklama örneğini başlatmak gibi gereksiz görevleri yerine getirir.

Yükleyin:

npm i --save puppeteer

Örnek - kullanıcı aracısını yazdırma

const puppeteer = require('puppeteer');

(async() => {
  const browser = await puppeteer.launch();
  console.log(await browser.version());
  await browser.close();
})();

Örnek: Sayfanın ekran görüntüsünü alma

const puppeteer = require('puppeteer');

(async() => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://www.chromestatus.com', {waitUntil: 'networkidle2'});
  await page.pdf({path: 'page.pdf', format: 'A4'});

  await browser.close();
})();

API'nin tamamı hakkında daha fazla bilgi edinmek için Puppeteer'ın belgelerine göz atın.

CRI kitaplığı

chrome-remote-interface Puppeteer API'sinden daha alt düzey bir kitaplıktır. Metne yakın olmak ve doğrudan DevTools protokolünü kullanmak istiyorsanız bunu yapmanızı öneririz.

Chrome başlatılıyor

chrome-remote-interface Chrome sizin için başlamaz, bu yüzden bu sorunu kendiniz halletmeniz gerekir.

KSA bölümünde --headless --remote-debugging-port=9222 kullanarak Chrome'u manuel olarak başlattık. Ancak, testleri tamamen otomatikleştirmek için muhtemelen uygulamanızdan Chrome oluşturmak istersiniz.

Bunlardan biri child_process işlevini kullanmaktır:

const execFile = require('child_process').execFile;

function launchHeadlessChrome(url, callback) {
  // Assuming MacOSx.
  const CHROME = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome';
  execFile(CHROME, ['--headless', '--disable-gpu', '--remote-debugging-port=9222', url], callback);
}

launchHeadlessChrome('https://www.chromestatus.com', (err, stdout, stderr) => {
  ...
});

Ancak birden fazla platformda çalışan taşınabilir bir çözüm arıyorsanız işler zor olabilir. Chrome'a giden şu sabit kodlu yola bakmanız yeterli :(

ChromeLauncher'ı kullanma

Lighthouse, web uygulamalarınızın kalitesini test etmek için harika bir araçtır. Lighthouse'ta Chrome'un başlatılması için sağlam bir modül geliştirildi ve artık bağımsız kullanım için çıkartılıyor. chrome-launcher NPM modülü Chrome'un yüklü olduğu yeri bulur, bir hata ayıklama örneği oluşturur, tarayıcıyı başlatır ve programınız bittiğinde devre dışı bırakır. En iyi yanı, Node sayesinde platformlar arası çalışması.

Varsayılan olarak, chrome-launcher, (yüklüyse) Chrome Canary'yi başlatmaya çalışır. Ancak kullanılacak Chrome'u manuel olarak seçmek için bunu değiştirebilirsiniz. Bunu kullanmak için önce npm'den yükleyin:

npm i --save chrome-launcher

Örnek: Gözetimsiz modu başlatmak için chrome-launcher kullanma

const chromeLauncher = require('chrome-launcher');

// Optional: set logging level of launcher to see its output.
// Install it using: npm i --save lighthouse-logger
// const log = require('lighthouse-logger');
// log.setLevel('info');

/**
 * Launches a debugging instance of Chrome.
 * @param {boolean=} headless True (default) launches Chrome in headless mode.
 *     False launches a full version of Chrome.
 * @return {Promise<ChromeLauncher>}
 */
function launchChrome(headless=true) {
  return chromeLauncher.launch({
    // port: 9222, // Uncomment to force a specific port of your choice.
    chromeFlags: [
      '--window-size=412,732',
      '--disable-gpu',
      headless ? '--headless' : ''
    ]
  });
}

launchChrome().then(chrome => {
  console.log(`Chrome debuggable on port: ${chrome.port}`);
  ...
  // chrome.kill();
});

Bu komut dosyasının çalıştırılması pek işe yaramaz, ancak about:blank dosyasını yükleyen görev yöneticisinde Chrome'un bir örneğini görürsünüz. Unutmayın, herhangi bir tarayıcı kullanıcı arayüzü olmayacaktır. Gözetimsiziz.

Tarayıcıyı kontrol etmek için Geliştirici Araçları protokolüne ihtiyacımız var.

Sayfa hakkında bilgi alınıyor

Kitaplığı yükleyelim:

npm i --save chrome-remote-interface
Örnekler

Örnek - kullanıcı aracısını yazdırma

const CDP = require('chrome-remote-interface');

...

launchChrome().then(async chrome => {
  const version = await CDP.Version({port: chrome.port});
  console.log(version['User-Agent']);
});

Şuna benzer şekilde sonuçlanıyor: HeadlessChrome/60.0.3082.0

Örnek: Sitenin bir web uygulaması manifesti içerip içermediğini kontrol edin.

const CDP = require('chrome-remote-interface');

...

(async function() {

const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});

// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const {Page} = protocol;
await Page.enable();

Page.navigate({url: 'https://www.chromestatus.com/'});

// Wait for window.onload before doing stuff.
Page.loadEventFired(async () => {
  const manifest = await Page.getAppManifest();

  if (manifest.url) {
    console.log('Manifest: ' + manifest.url);
    console.log(manifest.data);
  } else {
    console.log('Site has no app manifest');
  }

  protocol.close();
  chrome.kill(); // Kill Chrome.
});

})();

Örnek - DOM API'lerini kullanarak sayfanın <title> öğesini çıkarın.

const CDP = require('chrome-remote-interface');

...

(async function() {

const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});

// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const {Page, Runtime} = protocol;
await Promise.all([Page.enable(), Runtime.enable()]);

Page.navigate({url: 'https://www.chromestatus.com/'});

// Wait for window.onload before doing stuff.
Page.loadEventFired(async () => {
  const js = "document.querySelector('title').textContent";
  // Evaluate the JS expression in the page.
  const result = await Runtime.evaluate({expression: js});

  console.log('Title of page: ' + result.result.value);

  protocol.close();
  chrome.kill(); // Kill Chrome.
});

})();

Selenium, WebDriver ve ChromeDriver'ı kullanma

Selenium şu anda Chrome'un tam bir örneğini açmaktadır. Başka bir deyişle, tamamen gözetimsiz olmayan otomatik bir çözümdür. Bununla birlikte Selenium, küçük bir çalışmayla gözetimsiz Chrome'u çalıştıracak şekilde yapılandırılabilir. Ayarları kendi başınıza nasıl yapacağınızla ilgili tüm talimatları öğrenmek istiyorsanız Selenium'u Gözetimsiz Chrome ile Çalıştırma'yı öneririz. Başlamanız için aşağıya bazı örnekler ekledik.

ChromeDriver'ı kullanma

ChromeDriver 2.32, Chrome 61 sürümünü kullanır ve gözetimsiz Chrome ile iyi çalışır.

Yükleme:

npm i --save-dev selenium-webdriver chromedriver

Örnek:

const fs = require('fs');
const webdriver = require('selenium-webdriver');
const chromedriver = require('chromedriver');

const chromeCapabilities = webdriver.Capabilities.chrome();
chromeCapabilities.set('chromeOptions', {args: ['--headless']});

const driver = new webdriver.Builder()
  .forBrowser('chrome')
  .withCapabilities(chromeCapabilities)
  .build();

// Navigate to google.com, enter a search.
driver.get('https://www.google.com/');
driver.findElement({name: 'q'}).sendKeys('webdriver');
driver.findElement({name: 'btnG'}).click();
driver.wait(webdriver.until.titleIs('webdriver - Google Search'), 1000);

// Take screenshot of results page. Save to disk.
driver.takeScreenshot().then(base64png => {
  fs.writeFileSync('screenshot.png', new Buffer(base64png, 'base64'));
});

driver.quit();

WebDriverIO'yu kullanma

WebDriverIO, Selenium WebDriver'ın üzerinde yer alan daha üst düzey bir API'dir.

Yükleme:

npm i --save-dev webdriverio chromedriver

Örnek: chromestatus.com'da CSS özelliklerini filtreleme

const webdriverio = require('webdriverio');
const chromedriver = require('chromedriver');

const PORT = 9515;

chromedriver.start([
  '--url-base=wd/hub',
  `--port=${PORT}`,
  '--verbose'
]);

(async () => {

const opts = {
  port: PORT,
  desiredCapabilities: {
    browserName: 'chrome',
    chromeOptions: {args: ['--headless']}
  }
};

const browser = webdriverio.remote(opts).init();

await browser.url('https://www.chromestatus.com/features');

const title = await browser.getTitle();
console.log(`Title: ${title}`);

await browser.waitForText('.num-features', 3000);
let numFeatures = await browser.getText('.num-features');
console.log(`Chrome has ${numFeatures} total features`);

await browser.setValue('input[type="search"]', 'CSS');
console.log('Filtering features...');
await browser.pause(1000);

numFeatures = await browser.getText('.num-features');
console.log(`Chrome has ${numFeatures} CSS features`);

const buffer = await browser.saveScreenshot('screenshot.png');
console.log('Saved screenshot...');

chromedriver.stop();
browser.end();

})();

Diğer kaynaklar

Başlamanıza yardımcı olacak bazı faydalı kaynakları aşağıda bulabilirsiniz:

Belgeler

Araçlar

  • chrome-remote-interface - Geliştirici Araçları protokolünü sarmalayan düğüm modülü
  • Lighthouse - web uygulaması kalitesini test etmeye yönelik otomatik bir araçtır; protokolü yoğun bir şekilde kullanır
  • chrome-Başlatıcı - Chrome'u başlatmak için kullanılan, otomasyona hazır düğüm modülü

Demolar

  • "The Headless Web": Paul Kinlan'ın api.ai ile Gözetimsiz Web'i kullanma hakkındaki harika blog yayını.

SSS

--disable-gpu işaretine ihtiyacım var mı?

Yalnızca Windows'da. Diğer platformlar artık bunu gerektirmiyor. --disable-gpu işareti, birkaç hata için geçici bir çözümdür. Chrome'un gelecekteki sürümlerinde bu bayrağa ihtiyacınız olmayacaktır. Daha fazla bilgi için crbug.com/737678 adresini ziyaret edin.

Xvfb'ye hâlâ ihtiyacım var mı?

Hayır. Gözetimsiz Chrome'da pencere kullanılmadığı için Xvfb gibi bir görüntüleme sunucusuna gerek yoktur. Bu API olmadan otomatik testlerinizi memnuniyetle gerçekleştirebilirsiniz.

Xvfb nedir? Xvfb, fiziksel ekran olmadan grafik uygulamaları (Chrome gibi) çalıştırmanızı sağlayan Unix benzeri sistemlere yönelik bellek içi görüntüleme sunucusudur. Birçok kişi "gözetimsiz" test yapmak için Chrome'un önceki sürümlerini çalıştırmak üzere Xvfb'yi kullanır.

Gözetimsiz Chrome çalıştıran bir Docker container'ı nasıl oluşturabilirim?

fener-ci sitesine göz atın. Temel görüntü olarak node:8-slim etiketini kullanan ve App Engine Flex'te Lighthouse'u çalıştıranörnek bir Dockerfile öğesine sahiptir.

Bunu Selenyum / WebDriver / ChromeDriver ile kullanabilir miyim?

Evet. Selenium, WebDriver ve ChromeDriver'ı Kullanma başlıklı makaleye bakın.

Bunun PhantomJS ile olan ilişkisi nedir?

Gözetimsiz Chrome, PhantomJS gibi araçlara benzer. Her ikisi de gözetimsiz bir ortamda otomatik test için kullanılabilir. İkisi arasındaki temel fark, Phantom'un oluşturma motoru olarak WebKit'in eski bir sürümünü, Gözetimsiz Chrome'un ise Blink'in en son sürümünü kullanmasıdır.

Şu anda Phantom, DevTools protokolünden daha yüksek düzeyde bir API de sunmaktadır.

Hataları nereye bildirebilirim?

Headless Chrome ile ilgili hataları crbug.com adresinden bildirin.

Geliştirici Araçları protokolündeki hataları github.com/ChromeDevTools/devtools-protocol adresinden bildirebilirsiniz.