โหมดไม่มีส่วนหัวของ Chrome

Peter Kvitek
Peter Kvitek

ในปี 2017 Chrome 59 ได้เปิดตัวโหมดไม่มีส่วนหัว ซึ่งจะช่วยให้คุณเรียกใช้เบราว์เซอร์ในสภาพแวดล้อมที่ไม่มีผู้ดูแลได้โดยไม่มี UI ที่มองเห็นได้ และที่สำคัญ คุณสามารถใช้ Chrome โดยไม่ใช้ Chrome ได้

โหมดไม่มีส่วนหัวเป็นตัวเลือกยอดนิยมสำหรับการทำให้เบราว์เซอร์ทำงานอัตโนมัติผ่านโปรเจ็กต์ต่างๆ เช่น Puppeteer หรือ ChromeDriver ต่อไปนี้คือตัวอย่างบรรทัดคำสั่งขั้นต่ำที่ใช้โหมดไม่มีส่วนหัวเพื่อสร้างไฟล์ PDF ของ URL หนึ่งๆ

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

วิธีการทำงานของฟีเจอร์แบบไม่มีส่วนหัว

ก่อนที่เราจะมาทบทวนวิธีการทำงานของฟีเจอร์ "ไม่มีส่วนหัว" ในตอนนี้ คุณควรทำความเข้าใจวิธีการทำงานของ "ไม่มีส่วนหัว" "แบบเดิม" ก่อน ข้อมูลโค้ดบรรทัดคำสั่งก่อนหน้าใช้แฟล็กบรรทัดคำสั่ง --headless ซึ่งบ่งชี้ว่า Headless เป็นเพียงโหมดการทำงานของเบราว์เซอร์ Chrome ทั่วไป แต่ไม่น่าประหลาดใจว่านั่นไม่ใช่ความจริงเลย อันที่จริง Headless เวอร์ชันเก่าเป็นการใช้งานเบราว์เซอร์สำรองที่แยกต่างหากซึ่งมาพร้อมกับการจัดส่งโดยเป็นส่วนหนึ่งของไบนารี Chrome เดียวกัน และจะไม่แชร์โค้ดใดๆ ของเบราว์เซอร์ Chrome ใน //chrome

การติดตั้งใช้งานและดูแลรักษาเบราว์เซอร์แบบไม่มีส่วนหัวแยกต่างหากนั้นมีค่าใช้จ่ายทางวิศวกรรมมากมาย และเนื่องจาก Headless เป็นการติดตั้งใช้งานแยกต่างหาก โมเดลนี้จึงมีข้อบกพร่องและฟีเจอร์ต่างๆ ของตัวเองที่ไม่มีใน Chrome ซึ่งทำให้เกิดความสับสนในการทดสอบเบราว์เซอร์อัตโนมัติ ซึ่งอาจผ่านในโหมดส่วนหัว แต่ไม่สำเร็จในโหมดไม่มีส่วนหัว หรือในทางกลับกัน

นอกจากนี้ Headless ได้ไม่รวมการทดสอบอัตโนมัติใดๆ ที่ต้องอาศัยการติดตั้งส่วนขยายเบราว์เซอร์ เช่นเดียวกันกับฟังก์ชันอื่นๆ ระดับเบราว์เซอร์ เว้นแต่ว่า Headless จะมีการติดตั้งใช้งานของตัวเองและแยกต่างหาก ระบบไม่รองรับ

ตอนนี้ทีม Chrome ได้รวมโหมดไม่มีส่วนหัวและโหมดส่วนหัวเป็นแบบรวม

Chrome Headless ใหม่จะไม่เป็นการใช้งานเบราว์เซอร์แบบแยกต่างหากอีกต่อไป แต่ในตอนนี้ได้แชร์โค้ดกับ Chrome แทนแล้ว

โหมดไม่มีส่วนหัวใหม่พร้อมให้บริการใน Chrome 112 แล้ว ในโหมดนี้ Chrome จะสร้าง หน้าต่างของแพลตฟอร์มต่างๆ แต่ไม่แสดง ฟังก์ชันอื่นๆ ทั้งหมดทั้งที่มีอยู่แล้วและในอนาคตจะพร้อมใช้งานโดยไม่มีข้อจำกัด

ใช้โหมดไม่มีส่วนหัว

หากต้องการใช้โหมดไม่มีส่วนหัวใหม่ ให้ส่งแฟล็กบรรทัดคำสั่ง --headless=new ดังนี้

chrome --headless=new

สำหรับตอนนี้ โหมดไม่มีส่วนหัวแบบเก่าจะยังคงใช้ได้กับรุ่นต่อไปนี้

chrome --headless=old

ในเกมเชิดหุ่นกระบอก

วิธีเลือกใช้โหมดไม่มีส่วนหัวใหม่ใน 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

วิธีใช้โหมดไม่มีส่วนหัวใหม่ใน Selenium-WebDriver

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

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

// …

await driver.quit();

ดูข้อมูลเพิ่มเติมและตัวอย่างการใช้การเชื่อมโยงภาษาอื่นได้ที่บล็อกโพสต์ของทีม Selenium

แฟล็กบรรทัดคำสั่ง

แฟล็กบรรทัดคำสั่งต่อไปนี้พร้อมใช้งานในโหมดไม่มีส่วนหัวใหม่

--dump-dom

แฟล็ก --dump-dom จะพิมพ์ DOM ที่ทำให้เป็นอนุกรมของหน้าเป้าหมายไปยัง stdout เช่น

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

วิธีนี้แตกต่างจากการพิมพ์ซอร์สโค้ด HTML ซึ่งคุณอาจทำกับ curl เพื่อให้ได้เอาต์พุตของ --dump-dom ก่อนอื่น Chrome จะแยกวิเคราะห์โค้ด HTML ลงใน DOM และเรียกใช้ <script> ใดๆ ที่อาจแก้ไข DOM จากนั้นเปลี่ยน DOM นั้นกลับไปเป็นสตริง HTML แบบอนุกรม

--screenshot

แฟล็ก --screenshot ถ่ายภาพหน้าจอของหน้าเป้าหมายและบันทึกเป็น screenshot.png ในไดเรกทอรีที่ใช้งานอยู่ในปัจจุบัน วิธีนี้มีประโยชน์อย่างยิ่งเมื่อใช้ร่วมกับ Flag --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/

ไม่ได้: ฟังก์ชันที่อยู่เบื้องหลัง Flag --no-pdf-header-footer เคยใช้ได้กับแฟล็ก --print-to-pdf-no-header คุณอาจต้องกลับไปใช้ชื่อ Flag เดิมหากใช้เวอร์ชันก่อนหน้า

--timeout

แฟล็ก --timeout กำหนดเวลารอสูงสุด (หน่วยเป็นมิลลิวินาที) หลังจากนั้น --dump-dom, --screenshot และ --print-to-pdf จะบันทึกเนื้อหาในหน้าเว็บ แม้ว่าหน้าเว็บจะยังโหลดอยู่

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

ธง --timeout=5000 จะบอกให้ Chrome รอประมาณ 5 วินาทีก่อนพิมพ์ PDF ดังนั้น กระบวนการนี้จึงใช้เวลาสูงสุด 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 วินาที หน้าเว็บจะมี "1" หลังจากผ่านไป 2 วินาที "2" เป็นต้น วิธีบันทึกสถานะของหน้าเว็บหลังจากผ่านไป 42 วินาทีและบันทึกเป็น PDF มีดังนี้

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

--allow-chrome-scheme-url

ต้องใช้แฟล็ก --allow-chrome-scheme-url เพื่อเข้าถึง URL chrome:// รายการ แฟล็กนี้มีอยู่ใน Chrome 123 ตัวอย่าง

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

แก้ไขข้อบกพร่อง

เนื่องจาก Chrome จะมองไม่เห็นอย่างมีประสิทธิภาพในโหมดไม่มีส่วนหัว การแก้ปัญหาอาจฟังดูเป็นเรื่องยาก คุณอาจแก้ไขข้อบกพร่องของ Chrome แบบไม่มีส่วนหัวในลักษณะที่คล้ายคลึงกับ Chrome ที่มีส่วนหัวอย่างมากได้

เปิด Chrome ในโหมดไม่มีส่วนหัวด้วยแฟล็กบรรทัดคำสั่ง --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 ล่วงหน้า เราจะใช้การแก้ไขข้อบกพร่องระยะไกลในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome เพื่อเชื่อมต่อกับเป้าหมายแบบไม่มีส่วนหัวและตรวจสอบ

  1. ไปที่ chrome://inspect แล้วคลิกปุ่มกำหนดค่า...
  2. ป้อนที่อยู่ IP และหมายเลขพอร์ตจาก URL ของ WebSocket
    • ในตัวอย่างก่อนหน้านี้ ฉันป้อน 127.0.0.1:60926
  3. คลิกเสร็จ คุณควรเห็นเป้าหมายระยะไกลปรากฏขึ้นพร้อมกับแท็บทั้งหมดและเป้าหมายอื่นๆ ที่แสดงอยู่
  4. คลิกตรวจสอบเพื่อเข้าถึงเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome และตรวจสอบเป้าหมายแบบไม่มีส่วนหัวระยะไกล รวมถึงการดูหน้าแบบสด

เครื่องมือสำหรับนักพัฒนาเว็บใน Chrome สามารถตรวจสอบหน้าเป้าหมายแบบไม่มีส่วนหัวระยะไกล

ความคิดเห็น

เราหวังว่าจะได้รับความคิดเห็นจากคุณเกี่ยวกับโหมดไม่มีส่วนหัวแบบใหม่ หากพบปัญหา ให้รายงานข้อบกพร่อง