حالت بدون سر کروم

پیتر کویتک
Peter Kvitek

در سال 2017، Chrome 59 حالت Headless را معرفی کرد که به شما امکان می‌دهد مرورگر را در محیطی بدون نظارت و بدون هیچ رابط کاربری قابل مشاهده اجرا کنید. در اصل، می‌توانید کروم را بدون کروم اجرا کنید.

حالت بدون سر یک انتخاب محبوب برای اتوماسیون مرورگر، از طریق پروژه‌هایی مانند Puppeteer یا ChromeDriver است. در اینجا یک نمونه حداقل خط فرمان با استفاده از حالت Headless برای ایجاد یک فایل PDF از یک URL داده شده است:

chrome --headless --print-to-pdf https://developer.chrome.com/

هدلس چگونه کار می کند

قبل از اینکه اکنون نحوه عملکرد Headless را مرور کنیم، مهم است که بدانیم Headless "قدیمی" چگونه کار می کرد. قطعه خط فرمان قبلی از پرچم خط فرمان --headless استفاده می کند که نشان می دهد Headless فقط یک حالت عملکرد مرورگر معمولی کروم است. شاید جای تعجب باشد که این در واقع درست نبود. در واقع، Headless قدیمی یک پیاده سازی جداگانه و جایگزین مرورگر بود که اتفاقاً به عنوان بخشی از همان باینری کروم ارسال شد. هیچ یک از کدهای مرورگر کروم را در //chrome به اشتراک نمی گذارد.

پیاده سازی و نگهداری یک مرورگر Headless جداگانه با هزینه های مهندسی زیادی همراه بود. و از آنجایی که Headless یک پیاده‌سازی جداگانه بود، باگ‌ها و ویژگی‌های خاص خود را داشت که در Chrome headful وجود نداشت. این باعث سردرگمی برای تست‌های خودکار مرورگر شد، که ممکن است در حالت headful عبور کنند اما در حالت Headless شکست بخورند یا برعکس.

علاوه بر این، Headless هر آزمایش خودکاری را که به نصب برنامه افزودنی مرورگر متکی بود، حذف کرد. همین امر در مورد سایر عملکردهای سطح مرورگر نیز صدق می کند. مگر اینکه Headless پیاده سازی جداگانه خود را داشته باشد، پشتیبانی نمی شود.

تیم Chrome اکنون حالت‌های Headless و headful را یکپارچه کرده است.

Chrome Headless جدید دیگر یک پیاده سازی جداگانه مرورگر نیست و اکنون در عوض کد را با کروم به اشتراک می گذارد.

حالت جدید Headless از Chrome 112 در دسترس است. در این حالت، Chrome هیچ پنجره پلتفرمی ایجاد می‌کند، اما نمایش نمی‌دهد. همه توابع دیگر، موجود و آینده، بدون محدودیت در دسترس هستند.

از حالت Headless استفاده کنید

برای استفاده از حالت جدید Headless، پرچم --headless=new خط فرمان را ارسال کنید:

chrome --headless=new

در حال حاضر، حالت قدیمی Headless هنوز در دسترس است با:

chrome --headless=old

در بازی عروسکی

برای شرکت در حالت جدید Headless در Puppeteer:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  headless: 'new',
  // `headless: true` (default) enables old Headless;
  // `headless: 'new'` enables new Headless;
  // `headless: false` enables "headful" mode.
});

const page = await browser.newPage();
await page.goto('https://developer.chrome.com/');

// …

await browser.close();

در Selenium-WebDriver

برای استفاده از حالت جدید Headless در Selenium-WebDriver:

const driver = await env
  .builder()
  .setChromeOptions(options.addArguments('--headless=new'))
  .build();

await driver.get('https://developer.chrome.com/');

// …

await driver.quit();

برای اطلاعات بیشتر، از جمله نمونه هایی با استفاده از زبان های دیگر، به پست وبلاگ تیم سلنیوم مراجعه کنید.

پرچم های خط فرمان

پرچم‌های خط فرمان زیر در حالت جدید Headless در دسترس هستند.

--dump-dom

پرچم --dump-dom DOM سریالی صفحه مورد نظر را در stdout چاپ می کند. مثلا:

chrome --headless=new --dump-dom https://developer.chrome.com/

این با چاپ کد منبع HTML متفاوت است، که ممکن است با curl انجام دهید. برای اینکه خروجی --dump-dom را برای شما به ارمغان بیاورد، کروم ابتدا کد HTML را به یک DOM تجزیه می کند، هر <script> را که ممکن است DOM را تغییر دهد، اجرا می کند، سپس آن DOM را دوباره به رشته ای از HTML تبدیل می کند.

--screenshot

پرچم --screenshot یک عکس از صفحه مورد نظر می گیرد و آن را به عنوان screenshot.png در فهرست کاری فعلی ذخیره می کند. این به ویژه در ترکیب با پرچم --window-size مفید است.

مثلا:

chrome --headless=new --screenshot --window-size=412,892 https://developer.chrome.com/

--print-to-pdf

پرچم --print-to-pdf صفحه مورد نظر را به عنوان PDF با نام output.pdf در فهرست کاری فعلی ذخیره می کند. مثلا:

chrome --headless=new --print-to-pdf https://developer.chrome.com/

به صورت اختیاری، می‌توانید پرچم --no-pdf-header-footer را اضافه کنید تا سرصفحه چاپ (با تاریخ و زمان فعلی) و پاورقی (با URL و شماره صفحه) حذف شود.

chrome --headless=new --print-to-pdf --no-pdf-header-footer https://developer.chrome.com/

خیر: عملکرد پشت پرچم --no-pdf-header-footer قبلاً با پرچم --print-to-pdf-no-header در دسترس بود. در صورت استفاده از نسخه قبلی، ممکن است لازم باشد به نام پرچم قدیمی برگردید.

--timeout

پرچم --timeout حداکثر زمان انتظار (بر حسب میلی ثانیه) را مشخص می کند که پس از آن محتوای صفحه توسط --dump-dom ، --screenshot و --print-to-pdf ضبط می شود حتی اگر صفحه همچنان در حال بارگیری باشد.

chrome --headless=new --print-to-pdf --timeout=5000 https://developer.chrome.com/

پرچم --timeout=5000 به Chrome می گوید که قبل از چاپ PDF حداکثر 5 ثانیه صبر کند. بنابراین، اجرای این فرآیند حداکثر 5 ثانیه طول می کشد.

--virtual-time-budget

--virtual-time-budget به عنوان یک "سریع به جلو" برای هر کد وابسته به زمان عمل می کند (به عنوان مثال، setTimeout / setInterval ). مرورگر را مجبور می‌کند تا هر کدام از کدهای صفحه را با بیشترین سرعت ممکن اجرا کند، در حالی که باعث می‌شود صفحه باور کند که زمان واقعاً می‌گذرد.

برای نشان دادن کاربرد آن، این نسخه نمایشی را در نظر بگیرید، که با استفاده از setTimeout(fn, 1000) هر ثانیه یک شمارنده را افزایش، ثبت و نمایش می دهد . این هم کد مربوطه:

<output>0</output>
<script>
  const element = document.querySelector('output');
  let counter = 0;
  setInterval(() => {
    counter  ;
    console.log(counter);
    element.textContent = counter;
  }, 1_000);
</script>

پس از یک ثانیه، صفحه حاوی "1" است. پس از دو ثانیه، "2"، و غیره. در اینجا نحوه ثبت وضعیت صفحه پس از 42 ثانیه و ذخیره آن به صورت PDF آمده است:

chrome --headless=new --print-to-pdf --virtual-time-budget=42000 https://mathiasbynens.be/demo/time

--allow-chrome-scheme-url

برای دسترسی به URL های chrome:// پرچم --allow-chrome-scheme-url لازم است. این پرچم از Chrome 123 در دسترس است. مثالی در اینجا آمده است:

chrome --headless=new --print-to-pdf --allow-chrome-scheme-url chrome://gpu

اشکال زدایی

از آنجایی که Chrome در حالت Headless عملاً نامرئی است، ممکن است حل یک مشکل دشوار به نظر برسد. می توان Headless Chrome را به روشی بسیار شبیه به Chrome headful اشکال زدایی کرد.

Chrome را در حالت Headless با پرچم خط فرمان --remote-debugging-port راه اندازی کنید.

chrome --headless=new --remote-debugging-port=0 https://developer.chrome.com/

این یک URL منحصر به فرد WebSocket را برای stdout چاپ می کند، به عنوان مثال:

DevTools listening on ws://127.0.0.1:60926/devtools/browser/b4bd6eaa-b7c8-4319-8212-225097472fd9

در یک نمونه اصلی کروم، سپس می‌توانیم از اشکال‌زدایی از راه دور Chrome DevTools برای اتصال به هدف Headless و بررسی آن استفاده کنیم.

  1. به chrome://inspect بروید و روی دکمه Configure… کلیک کنید.
  2. آدرس IP و شماره پورت را از URL WebSocket وارد کنید.
    • در مثال قبلی 127.0.0.1:60926 را وارد کردم.
  3. روی Done کلیک کنید. باید ببینید که یک هدف از راه دور با تمام برگه‌ها و سایر اهداف فهرست شده ظاهر می‌شود.
  4. برای دسترسی به Chrome DevTools و بازرسی هدف Headless از راه دور، از جمله نمای زنده صفحه، بر روی Inspect کلیک کنید.

Chrome DevTools می‌تواند صفحه هدف Headless از راه دور را بازرسی کند

بازخورد

ما مشتاقانه منتظر شنیدن نظرات شما در مورد حالت جدید Headless هستیم. اگر با مشکلی مواجه شدید، یک اشکال را ثبت کنید .