מצב 'דפדפן Chrome ללא GUI'

Peter Kvitek
Peter Kvitek

ב-2017 הושק ב-Chrome 59 את מצב 'דפדפן ללא GUI', שמאפשר להפעיל את הדפדפן בסביבה ללא השגחה, ללא ממשק משתמש גלוי. בעיקרון, אפשר להפעיל את Chrome בלי Chrome.

מצב 'ללא GUI' הוא בחירה פופולרית לאוטומציה של דפדפנים, באמצעות פרויקטים כמו Puppeteer או ChromeDriver. הנה דוגמה מינימלית לשורת הפקודה באמצעות מצב 'ללא ממשק גרפי' ליצירת קובץ PDF של כתובת URL נתונה:

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

איך פועל טכנולוגיית 'דפדפן ללא GUI'

לפני שנבחן עכשיו איך טכנולוגיית 'דפדפן ללא ממשק גרפי' פועלת עכשיו, חשוב להבין איך טכנולוגיית 'דפדפן ללא ממשק גרפי' הישנה עבדה. קטע הקוד הקודם של שורת הפקודה משתמש בדגל שורת הפקודה --headless, רומז על כך ש-Headless הוא רק מצב פעולה של דפדפן Chrome הרגיל. באופן מפתיע, הטענה הזו לא הייתה נכונה. למעשה, הגרסה הישנה של Headless הייתה הטמעה נפרדת ואלטרנטיבית של הדפדפן, במקרה שנשלח כחלק מאותו בינארי של Chrome. הוא לא משתף שום קוד של דפדפן Chrome ב-//chrome.

ההטמעה והתחזוקה של דפדפן נפרד ללא ממשק גרפי כללו הרבה תקורה הנדסית. ומכיוון ש-Headless הייתה הטמעה נפרדת, היו לה באגים ותכונות שלא היו קיימים ב-Chrome הראשי. המצב הזה יצר בלבול בבדיקות אוטומטיות בדפדפן, שעשויות לעבור בהצלחה את המצב הנוכחי אבל להיכשל במצב 'דפדפן ללא GUI', או להיפך.

בנוסף, אפליקציית 'ללא GUI' החריגה כל בדיקה אוטומטית שהסתמכה על התקנה של תוסף לדפדפן. אותו עיקרון חל גם על פונקציות אחרות ברמת הדפדפן; אלא אם יש ל-Headless הטמעה נפרדת ונפרדת שלה, היא לא נתמכת.

צוות Chrome איחד עכשיו את המצבים 'דפדפן ללא GUI' ומצב 'ראשי'.

הגרסה החדשה של דפדפן Chrome כבר לא כוללת הטמעה נפרדת של הדפדפן. במקום זאת, היא משתפת קוד עם Chrome.

מצב 'דפדפן ללא GUI' זמין החל מ-Chrome 112. במצב הזה, Chrome יוצר, אבל לא מציג, חלונות פלטפורמה. כל שאר הפונקציות, הקיימות והעתידיות, זמינות ללא הגבלה.

שימוש במצב 'דפדפן ללא GUI'

כדי להשתמש במצב 'דפדפן ללא ממשק גרפי' החדש, מעבירים את דגל שורת הפקודה --headless=new:

chrome --headless=new

נכון לעכשיו, מצב 'דפדפן ללא GUI' הישן עדיין זמין עם:

chrome --headless=old

בבובת מונטיזציה

כדי להצטרף למצב החדש 'ללא GUI' ב-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();

למידע נוסף, כולל דוגמאות לקישורי שפות אחרים, ניתן לעיין בפוסט בבלוג של צוות סלניום.

התרעות לגבי שורת הפקודה

דגלי שורת הפקודה הבאים זמינים במצב 'דפדפן ללא ממשק גרפי' החדש.

--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 בספריית העבודה הנוכחית. זה שימושי במיוחד בשילוב עם הדגל --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 להמתין עד 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', אחרי שתי שניות, '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 מוסתר ביעילות במצב 'ללא GUI', יכול להיות שנשמע מסובך לפתור בעיה. אפשר לנפות באגים ב-Chrome ללא ממשק גרפי באופן שדומה מאוד ל-Chrome OS.

מפעילים את 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 ולוחצים על הלחצן Configure....
  2. מזינים את כתובת ה-IP ואת מספר היציאה מכתובת ה-URL של WebSocket.
    • בדוגמה הקודמת הזנתי 127.0.0.1:60926.
  3. לוחצים על סיום. היעד מרחוק אמור להופיע עם כל הכרטיסיות ויעדים אחרים ברשימה.
  4. לוחצים על inspect כדי לגשת לכלי הפיתוח ל-Chrome ולבדוק את היעד של השלט הרחוק, כולל צפייה בזמן אמת בדף.

כלי הפיתוח ל-Chrome יכולים לבדוק דף יעד מרוחק מסוג &#39;דפדפן ללא GUI&#39;

משוב

נשמח לקבל ממך משוב על מצב 'ללא GUI' החדש. אם נתקלים בבעיות, אפשר לדווח על באג.