बिना ग्राफ़िक यूज़र इंटरफ़ेस वाले Chrome का इस्तेमाल शुरू करना

लेख पढ़ें.

कम शब्दों में कहा जाए तो

बिना ग्राफ़िक यूज़र इंटरफ़ेस वाला Chrome, Chrome 59 में उपलब्ध है. यह हेडलेस एनवायरमेंट में Chrome ब्राउज़र को चलाने का एक तरीका है. इसका मतलब है कि Chrome के बिना, Chrome चलाना! यह कमांड लाइन में, Chromium और Blink रेंडरिंग इंजन की वेब प्लैटफ़ॉर्म की सभी आधुनिक सुविधाएं उपलब्ध कराता है.

यह जानकारी आपके काम की क्यों है?

हेडलेस ब्राउज़र, ऑटोमेटेड टेस्टिंग और सर्वर एनवायरमेंट के लिए एक बेहतरीन टूल है. उदाहरण के लिए, हो सकता है कि आपको किसी असली वेब पेज पर कुछ टेस्ट चलाने हों, उसका PDF बनाना हो या सिर्फ़ यह जांचना हो कि ब्राउज़र किसी यूआरएल को कैसे रेंडर करता है.

बिना यूज़र इंटरफ़ेस वाला ब्राउज़र (सीएलआई) शुरू करना

हेडलेस मोड का इस्तेमाल शुरू करने का सबसे आसान तरीका यह है कि कमांड लाइन से Chrome बाइनरी खोला जाए. अगर आपने Chrome 59 या इसके बाद का वर्शन इंस्टॉल किया हुआ है, तो --headless फ़्लैग के साथ Chrome शुरू करें:

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 के इंस्टॉलेशन पर ले जाना चाहिए. जगह की सटीक जानकारी, प्लैटफ़ॉर्म के हिसाब से अलग-अलग होगी. मेरे पास Mac है. इसलिए, मैंने Chrome के हर इंस्टॉल किए गए वर्शन के लिए, आसानी से इस्तेमाल किए जा सकने वाले उपनाम बनाए हैं.

अगर आपने Chrome का स्टेबल चैनल चुना है और आपको बीटा वर्शन नहीं मिल रहा है, तो हमारा सुझाव है कि आप chrome-canary का इस्तेमाल करें:

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 को यहां डाउनलोड करें.

कमांड लाइन की सुविधाएं

कुछ मामलों में, हो सकता है कि आपको Headless Chrome को प्रोग्राम के हिसाब से स्क्रिप्ट न करनी पड़े. सामान्य काम करने के लिए, काम के कमांड-लाइन फ़्लैग उपलब्ध हैं.

डीओएम को प्रिंट करना

--dump-dom फ़्लैग, स्टैंडर्ड आउटपुट में document.body.innerHTML को प्रिंट करता है:

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

PDF बनाना

--print-to-pdf फ़्लैग, पेज का PDF बनाता है:

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

स्क्रीनशॉट लेना

किसी पेज का स्क्रीनशॉट लेने के लिए, --screenshot फ़्लैग का इस्तेमाल करें:

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 के साथ चलाने पर, मौजूदा वर्किंग डायरेक्ट्री में screenshot.png नाम की फ़ाइल बन जाएगी. अगर आपको पूरे पेज के स्क्रीनशॉट चाहिए, तो इसके लिए थोड़ी ज़्यादा मेहनत करनी पड़ती है. डेविड श्नूर की एक बेहतरीन ब्लॉग पोस्ट है, जिसमें इस बारे में पूरी जानकारी दी गई है. बिना ग्राफ़िक यूज़र इंटरफ़ेस वाले Chrome ब्राउज़र को, ऑटोमेटेड स्क्रीनशॉट टूल के तौर पर इस्तेमाल करने के बारे में जानें.

आरईपीएल मोड (रीड-इवैल्यूएट-प्रिंट लूप)

--repl फ़्लैग, हेडलेस मोड में काम करता है. इस मोड में, कमांड लाइन से ब्राउज़र में JS एक्सप्रेशन का आकलन किया जा सकता है:

$ 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
$

क्या आपको ब्राउज़र यूज़र इंटरफ़ेस (यूआई) के बिना Chrome को डीबग करना है?

--remote-debugging-port=9222 के साथ Chrome चलाने पर, यह DevTools प्रोटोकॉल चालू करके एक इंस्टेंस शुरू करता है. इस प्रोटोकॉल का इस्तेमाल, Chrome के साथ इंटरैक्ट करने और हेडलेस ब्राउज़र इंस्टेंस को चलाने के लिए किया जाता है. Sublime, VS Code, और Node जैसे टूल भी किसी ऐप्लिकेशन को रिमोट से डीबग करने के लिए, इस प्रोटोकॉल का इस्तेमाल करते हैं. #synergy

पेज देखने के लिए, आपके पास ब्राउज़र यूज़र इंटरफ़ेस (यूआई) नहीं है. इसलिए, किसी दूसरे ब्राउज़र में http://localhost:9222 पर जाएं और देखें कि सब कुछ ठीक से काम कर रहा है या नहीं. आपको ऐसे पेजों की सूची दिखेगी जिनकी जांच की जा सकती है. यहां क्लिक करके, यह देखा जा सकता है कि हेडलेस क्या रेंडर कर रहा है:

DevTools रिमोट
DevTools का रिमोट डीबगिंग यूज़र इंटरफ़ेस (यूआई)

यहां से, पेज की जांच करने, उसे डीबग करने, और उसमें बदलाव करने के लिए, DevTools की सुविधाओं का इस्तेमाल किया जा सकता है. अगर प्रोग्राम के हिसाब से हेडलेस का इस्तेमाल किया जा रहा है, तो यह पेज एक बेहतरीन डीबगिंग टूल भी है. इसकी मदद से, ब्राउज़र के साथ इंटरैक्ट करने वाले, वायर पर भेजे जाने वाले सभी रॉ DevTools प्रोटोकॉल कमांड देखे जा सकते हैं.

प्रोग्राम के हिसाब से (Node) इस्तेमाल करना

Puppeteer

Puppeteer, Chrome टीम की बनाई गई एक Node लाइब्रेरी है. यह हेडलेस (या पूरे) Chrome को कंट्रोल करने के लिए, हाई-लेवल एपीआई उपलब्ध कराता है. यह Phantom और NightmareJS जैसी ऑटोमेटेड टेस्टिंग लाइब्रेरी से मिलती-जुलती है. हालांकि, यह सिर्फ़ Chrome के नए वर्शन के साथ काम करती है.

Puppeteer का इस्तेमाल, कई कामों के लिए किया जा सकता है. जैसे, आसानी से स्क्रीनशॉट लेना, PDF बनाना, पेजों पर नेविगेट करना, और उन पेजों के बारे में जानकारी फ़ेच करना. अगर आपको ब्राउज़र टेस्टिंग को तेज़ी से ऑटोमेट करना है, तो हमारा सुझाव है कि आप लाइब्रेरी का इस्तेमाल करें. यह DevTools प्रोटोकॉल की जटिलताओं को छिपा देता है और Chrome के डीबग इंस्टेंस को लॉन्च करने जैसे ग़ैर-ज़रूरी कामों को पूरा करता है.

इसे इंस्टॉल करने के लिए:

npm i --save puppeteer

उदाहरण - उपयोगकर्ता एजेंट को प्रिंट करना

const puppeteer = require('puppeteer');

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

उदाहरण - पेज का स्क्रीनशॉट लेना

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();
})();

पूरे एपीआई के बारे में ज़्यादा जानने के लिए, Puppeteer का दस्तावेज़ देखें.

सीआरआई लाइब्रेरी

chrome-remote-interface, Puppeteer के एपीआई की तुलना में एक लोअर-लेवल लाइब्रेरी है. हमारा सुझाव है कि अगर आपको DevTools प्रोटोकॉल का सीधे तौर पर इस्तेमाल करना है, तो इस टूल का इस्तेमाल करें.

Chrome लॉन्च करना

chrome-remote-interface, Chrome को आपके लिए लॉन्च नहीं करता. इसलिए, आपको खुद ही इसकी देखभाल करनी होगी.

सीएलआई सेक्शन में, हमने --headless --remote-debugging-port=9222 का इस्तेमाल करके Chrome को मैन्युअल तरीके से शुरू किया. हालांकि, जांचों को पूरी तरह से ऑटोमेट करने के लिए, आपको अपने ऐप्लिकेशन से Chrome को स्पैन करना होगा.

child_process का इस्तेमाल करके, ऐसा किया जा सकता है:

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) => {
  ...
});

हालांकि, अगर आपको एक ऐसा समाधान चाहिए जो एक से ज़्यादा प्लैटफ़ॉर्म पर काम करे, तो समस्याएं बढ़ जाती हैं. Chrome के लिए हार्ड कोड किए गए पाथ को देखें :(

ChromeLauncher का इस्तेमाल करना

Lighthouse, आपके वेब ऐप्लिकेशन की क्वालिटी की जांच करने के लिए एक बेहतरीन टूल है. Lighthouse में, Chrome को लॉन्च करने के लिए एक मज़बूत मॉड्यूल बनाया गया था. अब इसे स्टैंडअलोन तौर पर इस्तेमाल करने के लिए निकाला गया है. chrome-launcher NPM मॉड्यूल, Chrome के इंस्टॉल होने की जगह ढूंढेगा, डीबग इंस्टेंस सेट अप करेगा, ब्राउज़र को लॉन्च करेगा, और प्रोग्राम पूरा होने पर उसे बंद कर देगा. सबसे अच्छी बात यह है कि यह Node की मदद से, क्रॉस-प्लैटफ़ॉर्म पर काम करता है!

डिफ़ॉल्ट रूप से, chrome-launcher Chrome Canary को लॉन्च करने की कोशिश करेगा. हालांकि, इसे मैन्युअल तरीके से बदलकर, यह चुना जा सकता है कि किस Chrome का इस्तेमाल करना है. इसका इस्तेमाल करने के लिए, सबसे पहले npm से इंस्टॉल करें:

npm i --save chrome-launcher

उदाहरण - हेडलेस मोड को लॉन्च करने के लिए chrome-launcher का इस्तेमाल करना

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();
});

इस स्क्रिप्ट को चलाने से ज़्यादा कुछ नहीं होता. हालांकि, आपको टास्क मैनेजर में about:blank को लोड करने वाले Chrome का एक इंस्टेंस दिखेगा. याद रखें कि इसमें ब्राउज़र का यूज़र इंटरफ़ेस (यूआई) नहीं होगा. हम बिना ग्राफ़िक यूज़र इंटरफ़ेस वाला ब्राउज़र हैं.

ब्राउज़र को कंट्रोल करने के लिए, हमें DevTools प्रोटोकॉल की ज़रूरत है!

पेज के बारे में जानकारी हासिल करना

चलिए, लाइब्रेरी इंस्टॉल करते हैं:

npm i --save chrome-remote-interface
उदाहरण

उदाहरण - उपयोगकर्ता एजेंट को प्रिंट करना

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

...

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

इस तरह के नतीजे मिलेंगे: HeadlessChrome/60.0.3082.0

उदाहरण - देखें कि साइट में वेब ऐप्लिकेशन मेनिफ़ेस्ट है या नहीं

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.
});

})();

उदाहरण - DOM API का इस्तेमाल करके, पेज का <title> निकालें.

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, और ChromeDriver का इस्तेमाल करना

फ़िलहाल, Selenium Chrome का पूरा इंस्टेंस खोलता है. दूसरे शब्दों में, यह एक ऑटोमेटेड समाधान है, लेकिन पूरी तरह हेडलेस नहीं है. हालांकि, Selenium को थोड़े से काम के साथ हेडलेस Chrome चलाने के लिए कॉन्फ़िगर किया जा सकता है. अगर आपको खुद से सेट अप करने का पूरा तरीका जानना है, तो हमारा सुझाव है कि आप Headless Chrome के साथ Selenium चलाएं. हालांकि, हमने यहां कुछ उदाहरण दिए हैं, ताकि आपको शुरुआत करने में मदद मिल सके.

ChromeDriver का इस्तेमाल करना

ChromeDriver 2.32, Chrome 61 का इस्तेमाल करता है और बिना ग्राफ़िक यूज़र इंटरफ़ेस वाले Chrome के साथ बेहतर तरीके से काम करता है.

इंस्टॉल करें:

npm i --save-dev selenium-webdriver chromedriver

उदाहरण:

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 का इस्तेमाल करना

WebDriverIO, Selenium WebDriver के ऊपर एक बेहतर लेवल का एपीआई है.

इंस्टॉल करें:

npm i --save-dev webdriverio chromedriver

उदाहरण: chromestatus.com पर सीएसएस की सुविधाओं को फ़िल्टर करना

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();

})();

अतिरिक्त संसाधन

यहां कुछ काम के संसाधन दिए गए हैं, जिनकी मदद से आपको शुरुआत करने में मदद मिलेगी:

Docs

टूल

  • chrome-remote-interface - DevTools प्रोटोकॉल को रैप करने वाला नोड मॉड्यूल
  • Lighthouse - वेब ऐप्लिकेशन की क्वालिटी की जांच करने के लिए, अपने-आप काम करने वाला टूल. यह प्रोटोकॉल का ज़्यादा इस्तेमाल करता है
  • chrome-launcher - Chrome को लॉन्च करने के लिए नोड मॉड्यूल, ऑटोमेशन के लिए तैयार

डेमो

  • "Headless वेब" - Paul Kinlan की api.ai के साथ Headless का इस्तेमाल करने के बारे में बेहतरीन ब्लॉग पोस्ट.

अक्सर पूछे जाने वाले सवाल

क्या मुझे --disable-gpu फ़्लैग की ज़रूरत है?

सिर्फ़ Windows पर. अन्य प्लैटफ़ॉर्म के लिए, अब इसकी ज़रूरत नहीं है. --disable-gpu फ़्लैग, कुछ गड़बड़ियों को ठीक करने के लिए कुछ समय के लिए इस्तेमाल किया जाता है. Chrome के आने वाले वर्शन में, आपको इस फ़्लैग की ज़रूरत नहीं होगी. ज़्यादा जानकारी के लिए, crbug.com/737678 पर जाएं.

क्या मुझे अब भी Xvfb की ज़रूरत है?

नहीं. Headless Chrome में विंडो का इस्तेमाल नहीं किया जाता. इसलिए, अब Xvfb जैसे डिसप्ले सर्वर की ज़रूरत नहीं है. इसके बिना भी, अपने-आप चलने वाले टेस्ट आसानी से चलाए जा सकते हैं.

Xvfb क्या है? Xvfb, Unix जैसे सिस्टम के लिए एक इन-मेमोरी डिसप्ले सर्वर है. इसकी मदद से, किसी डिसप्ले के बिना भी Chrome जैसे ग्राफ़िकल ऐप्लिकेशन चलाए जा सकते हैं. कई लोग "बिना ग्राफ़िक यूज़र इंटरफ़ेस वाले" वर्शन की जांच करने के लिए, Chrome के पुराने वर्शन चलाने के लिए Xvfb का इस्तेमाल करते हैं.

मैं Headless Chrome चलाने वाला Docker कंटेनर कैसे बनाऊं?

lighthouse-ci देखें. इसमें एक उदाहरण के तौर पर Dockerfile है, जो node:8-slim को बेस इमेज के तौर पर इस्तेमाल करता है. साथ ही, App Engine Flex पर Lighthouse को इंस्टॉल और चलाता है.

क्या इसका इस्तेमाल Selenium / WebDriver / ChromeDriver के साथ किया जा सकता है?

हां. Selenium, WebDriver, और ChromeDriver का इस्तेमाल करना लेख पढ़ें.

यह PhantomJS से कैसे जुड़ा है?

Headless Chrome, PhantomJS जैसे टूल से मिलता-जुलता है. दोनों का इस्तेमाल, हेडलेस एनवायरमेंट में ऑटोमेटेड टेस्टिंग के लिए किया जा सकता है. इन दोनों के बीच मुख्य अंतर यह है कि Phantom, रेंडरिंग इंजन के तौर पर WebKit के पुराने वर्शन का इस्तेमाल करता है, जबकि Headless Chrome, Blink के नए वर्शन का इस्तेमाल करता है.

फ़िलहाल, Phantom DevTools प्रोटोकॉल के मुकाबले, ज़्यादा लेवल का एपीआई भी उपलब्ध कराता है.

मैं गड़बड़ियों की शिकायत कहां करूं?

Headless Chrome से जुड़ी गड़बड़ियों की शिकायत करने के लिए, crbug.com पर जाएं.

DevTools प्रोटोकॉल में मौजूद गड़बड़ियों की शिकायत करने के लिए, github.com/ChromeDevTools/devtools-protocol पर जाएं.