.
Ö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. Temelde, Chrome'u Chrome olmadan çalıştırmak! Chromium ve Blink oluşturma motorunun sağladığı tüm modern web platformu özelliklerini komut satırına taşır.
Neden faydalı oldu?
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 harika bir araçtır. Örneğin, gerçek bir web sayfası üzerinde bazı testler yapmak, bunun bir PDF dosyasını oluşturmak veya sadece tarayıcının bir URL'yi nasıl oluşturduğunu incelemek isteyebilirsiniz.
Gözetimsiz (CLI) başlatılıyor
Gözetimsiz modu kullanmaya başlamanın en kolay yolu, Chrome ikili programını komut satırından 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şiklik gösterecektir. Mac'te olduğumdan, yüklediğim her Chrome
sürümü için pratik takma adlar oluşturdum.
Chrome'un mevcut ürün kanalını kullanıyor 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 şekilde kodlamanız gerekmeyebilir. Yaygın görevleri gerçekleştirmek için bazı kullanışlı komut satırı işaretleri vardır.
DOM'yi yazdırma
--dump-dom
işareti, document.body.innerHTML
değerini stdout'a yazdırır:
chrome --headless --disable-gpu --dump-dom https://www.chromestatus.com/
PDF oluşturma
--print-to-pdf
işareti sayfanın PDF'sini 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
işler biraz daha karmaşıktır. David Schnurr'dan harika bir blog
yayını var. Gözetimsiz Chrome'u otomatik ekran görüntüsü aracı olarak kullanma
konusuna göz atın.
REPL modu (oku-eval-yazdırma döngüsü)
--repl
işareti, JS ifadelerini doğrudan komut satırından tarayıcıda değerlendirebileceğiniz bir modda çalışı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'da hata ayıklanıyor mu?
Chrome'u --remote-debugging-port=9222
ile çalıştırdığınızda, DevTools protokolü etkinleştirilmiş bir örnek başlatır. Protokol, Chrome ile iletişim kurmak ve gözetimsiz tarayıcı örneğini çalıştırmak için kullanılır. Ayrıca Sublime, VS Code ve Node gibi araçların uygulamalarda uzaktan hata ayıklaması için de kullandığı araçlardır. #synergy
Sayfayı görmek 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. İncelenebilir sayfaların bir listesini burada tıklayarak ilgili sayfaları tıklayıp Gözetimsiz'in ne oluşturduğunu görebilirsiniz:

Buradan, sayfayı her zamanki gibi denetlemek, hata ayıklamak ve ince ayar yapmak için bilindik Geliştirici Araçları özelliklerini kullanabilirsiniz. Headless'i programatik olarak kullanıyorsanız bu sayfa, tüm ham DevTools protokol komutlarını kablodan geçerek tarayıcıyla iletişim kurmak için de kullanabileceğiniz 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, başka işlevlerinin yanı sıra kolayca ekran görüntüsü almak, PDF oluşturmak, sayfalarda gezinmek ve bu sayfalar hakkında bilgi getirmek için kullanılabilir. Tarayıcı testini hızlı bir şekilde otomatikleştirmek istiyorsanız kitaplığı kullanmanızı öneririz. DevTools protokolünün karmaşıklığını ortadan kaldırır 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();
})();
Tam API hakkında daha fazla bilgi edinmek için Puppeteer belgelerine göz atın.
CRI kitaplığı
chrome-remote-interface Puppeteer'ın API'sinden daha düşük düzeyde bir kitaplıktır. Metal kullanmaya yakın olmak ve doğrudan DevTools protokolünü kullanmak istiyorsanız bu seçeneği öneririz.
Chrome başlatılıyor
chrome-remote-interface Chrome'u sizin için başlatmaz, dolayısıyla bununla sizin ilgilenmeniz gerekir.
KSA bölümünde --headless --remote-debugging-port=9222
ile Chrome'u manuel olarak başlattık. Ancak, testleri tamamen otomatikleştirmek için muhtemelen Chrome'u uygulamanızdan oluşturmak istersiniz.
Bunun bir yolu child_process
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 çok platformda çalışan taşınabilir bir çözüm istediğinizde işler zorlaşabilir. Chrome'un kodu içeren bu yola bakın :(
ChromeLauncher'ı kullanma
Lighthouse, web uygulamalarınızın kalitesini
test etmek için harika bir araçtır. Lighthouse'da Chrome'u başlatmak için sağlam bir modül geliştirildi ve artık bağımsız kullanım için ayıklandı.
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 tamamlandığında sonlandırır. En iyi yanı da Node sayesinde farklı platformlarda
çalışmasıdır.
Varsayılan olarak, chrome-launcher
, Chrome Canary'yi başlatmayı dener (yüklüyse) ancak bunu değiştirerek hangi Chrome'un kullanılacağını manuel olarak seçebilirsiniz. Kullanmak için önce npm'den yükleyin:
npm i --save chrome-launcher
Örnek - Headless'i 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ı çalıştırmak pek işe yaramaz ancak about:blank
uygulamasını yükleyen görev yöneticisinde Chrome'un bir örneğinin etkinleştiğini göreceksiniz. Unutmayın, herhangi bir tarayıcı arayüzü olmaz. Gözetimimiz yok.
Tarayıcıyı kontrol etmek için Geliştirici Araçları protokolüne ihtiyacımız vardır.
Sayfa hakkında bilgi alma
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 bir sonuçla sonuçlanır: HeadlessChrome/60.0.3082.0
Örnek - Sitenin web uygulaması manifesti olup olmadığını 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
Şu anda Selenium, Chrome'un tam örneğini açıyor. Başka bir deyişle, bu otomatik bir çözümdür, ancak tamamen gözetimsiz değildir. Ancak Selenium, gözetimsiz Chrome'u biraz çalışarak çalıştıracak şekilde yapılandırılabilir. Ayarları kendi başınıza nasıl yapacağınızla ilgili tüm talimatları görmek isterseniz Selenium'u gözetimsiz Chrome ile çalıştırmayı öneririz. Ancak başlamanıza yardımcı olmak 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 bir şekilde ç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 üzerine yer alan daha yüksek düzey bir API'dir.
Yükleme:
npm i --save-dev webdriverio chromedriver
Örnek: chromestatus.com adresindeki 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ı yararlı kaynakları aşağıda bulabilirsiniz:
Belgeler
- DevTools Protokol Görüntüleyici - API referans belgeleri
Araçlar
- chrome-remote-interface - DevTools protokolünü sarmalayan düğüm modülü
- Lighthouse - Web uygulaması kalitesini test etmek için kullanılan otomatik araç; 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 Headless'i api.ai ile kullanma hakkındaki harika blog yayını.
SSS
--disable-gpu
işaretini kullanmam gerekir mi?
Yalnızca Windows'da. Diğer platformlar için artık gerekli değil. --disable-gpu
işareti, birkaç hatayla ilgili geçici bir çözümdür. Chrome'un gelecekteki sürümlerinde bu işarete ihtiyacınız
olmayacaktır. Daha fazla bilgi için crbug.com/737678 adresini inceleyin.
Yani hâlâ Xvfb'ye ihtiyacım var mı?
Hayır. Gözetimsiz Chrome'da pencere kullanılmadığı için Xvfb gibi bir görüntülü reklam sunucusuna ihtiyaç yoktur. Bu olmadan da otomatik testlerinizi yapabilirsiniz.
Xvfb nedir? Xvfb, fiziksel bir ekran olmadan grafik uygulamaları (Chrome gibi) çalıştırabilmenizi sağlayan, Unix benzeri sistemler için kullanılan bir bellek içi görüntüleme sunucusudur. Birçok kişi "gözetimsiz" testler gerçekleştirmek üzere Chrome'un önceki sürümlerini çalıştırmak için Xvfb'yi kullanır.
Gözetimsiz Chrome çalıştıran Docker container'ını nasıl oluşturabilirim?
window-ci'ye göz atın. Temel görüntü olarak node:8-slim
kullanan örnek bir Dockerfile vardır ve App Engine Flex'te Lighthouse'u ve Lighthouse'u çalıştırır.
Bunu Selenium / WebDriver / ChromeDriver ile kullanabilir miyim?
Evet. Selenium, WebDriver ve ChromeDriver'ı kullanma başlıklı makaleye bakın.
Bunun PhantomJS ile ne ilgisi var?
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ü kullanırken, Headless Chrome'un Blink'in en son sürümünü kullanmasıdır.
Phantom şu anda DevTools protokolü'nden daha yüksek düzeyde bir API sunuyor.
Hataları nereye bildirebilirim?
Headless Chrome ile ilgili hataları crbug.com adresinden kaydedin.
DevTools protokolündeki hataları github.com/ChromeDevTools/devtools-protocol adresinden bildirebilirsiniz.