बिना ग्राफ़िक यूज़र इंटरफ़ेस वाले 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 कैनरी को यहां से डाउनलोड करें.

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

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

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

--dump-dom फ़्लैग document.body.innerHTML को stdout पर प्रिंट करता है:

    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 मोड (रीड-ईवल-प्रिंट लूप)

--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 प्रोटोकॉल कमांड देखे जा सकते हैं.

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

Puppeteer

Puppeteer एक नोड लाइब्रेरी है, जिसे Chrome टीम ने डेवलप किया है. यह बिना ग्राफ़िक यूज़र इंटरफ़ेस वाले 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, यूनिक्स जैसे सिस्टम के लिए इन-मेमोरी डिसप्ले सर्वर है, जिसकी मदद से आप बिना किसी फ़िज़िकल डिसप्ले के अटैच किए हुए ग्राफ़िकल ऐप्लिकेशन (जैसे Chrome) चला सकते हैं. कई लोग "हेडलेस" टेस्टिंग के लिए, Chrome के पुराने वर्शन चलाने के लिए Xvfb का इस्तेमाल करते हैं.

मैं ऐसा Docker कंटेनर कैसे बनाऊं जो बिना ग्राफ़िक यूज़र इंटरफ़ेस वाला Chrome चलाता है?

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 पर जाकर उनकी शिकायत करें.