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

एरिक बिडेलमैन

को पढ़ें.

बहुत ज़्यादा शब्द हैं, पढ़ा नहीं गया

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

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

बिना ग्राफ़िक यूज़र इंटरफ़ेस वाला ब्राउज़र, अपने-आप टेस्ट करने और सर्वर एनवायरमेंट के लिए बेहतरीन टूल है. इस टूल में, दिखने वाले यूज़र इंटरफ़ेस (यूआई) शेल की ज़रूरत नहीं होती. उदाहरण के लिए, हो सकता है कि आप किसी असली वेब पेज की जांच करके, उसका PDF बनाना चाहें या जांचें कि ब्राउज़र, यूआरएल को कैसे रेंडर करता है.

शुरुआती हेडलेस (सीएलआई)

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

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

--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 को डीबग करना है?

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

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

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

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

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

कठपुतली का किरदार

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

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 का हार्ड कोड किया गया पाथ देखें :(

Chromeलॉन्चर का इस्तेमाल करना

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

डिफ़ॉल्ट रूप से, chrome-launcher Chrome कैनरी (अगर इंस्टॉल किया गया हो) को लॉन्च करने की कोशिश करेगा, लेकिन आपके पास इसे बदलकर मैन्युअल तौर पर यह चुनने का विकल्प है कि कौनसा 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();
});

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

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

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 सेलेनियम 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 को लॉन्च करने के लिए नोड मॉड्यूल, ऑटोमेशन के लिए तैयार है

डेमो

  • "द हेडलेस वेब" - api.ai के साथ हेडलेस के इस्तेमाल के बारे में पॉल किनलन का शानदार ब्लॉग पोस्ट.

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

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

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

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

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

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

मैं ऐसा Docker कंटेनर कैसे बनाऊं जो हेडलेस Chrome को चलाता हो?

लाइटहाउस-सीआई देखें. इसमें Dockerfile का एक उदाहरण दिया गया है, जो node:8-slim को बेस इमेज के तौर पर इस्तेमाल करता है, App Engine Flex पर Lighthouse को इंस्टॉल + चलाता है.

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

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

यह PhantomJS से कैसे संबंधित है?

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

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

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

हेडलेस Chrome से जुड़ी गड़बड़ियों को crbug.com पर दर्ज करें.

DevTools प्रोटोकॉल में गड़बड़ियां ढूंढने के लिए, github.com/ChromeDevTools/devtools-protocol पर उन्हें फ़ाइल करें.