Proszę o przekazywanie wsparcia w ramach 1 proc. podatku dla Krzysia Bulczaka, największego bohatera, jakiego znam. KRS 0000037904 z dopiskiem 20374 Bulczak Krzysztof

Headless Chrome

A gdyby tak z przeglądarki Chrome wyrzucić cały interfejs graficzny i korzystać z niej wyłącznie w trybie komend wpisywanych w terminalu? Takie rozwiązanie ma sens dla wielu zadań związanych z dokumentowaniem i badaniem zasobów WWW.

Headless Chrome

Przeglądarki już dawno przestały być wyłącznie oprogramowaniem do wyświetlania stron WWW. To dziś, także dzięki bogatym bazom dostępnych wtyczek, pełnoprawne środowiska pracy, nadające się do prowadzenia badań (Zotero Connector) czy programowania, debugowania i ewaluacji stron WWW (np. DevTools oraz Lighthouse w Chrome). Wykorzystując przeglądarkę do standardowych zadań często nie mamy pojęcia, co jeszcze można z nią zrobić.

Jeśli korzystamy z Google Chrome lub Chromium, mamy do dyspozycji użyteczne narzędzie do programowego przetwarzania stron WWW. Tryb Headless, dostępny choćby w przeglądarkach Chromium/Chrome, udostępnia łatwe w użyciu środowisko interpretowania stron internetowych. W ten sposób można nie tylko błyskawicznie wygenerować zrzut ekranu (dla dowolnej rozdzielczości ekranu) czy plik PDF z treścią strony, ale także wesprzeć dynamiczne pozyskiwanie ze stron wybranych informacji (Web scraping). Póki co w tej notce zajmę się prostymi przykładami niewymagającymi programowania.

Chrome w terminalu

Na początku pracy z przeglądarką w trybie headless musimy znaleźć komendę, która uruchomi ją z poziomu terminalu. Pracuję na Ubuntu, mam zainstalowaną i Chrome i Chromium: aby odkryć, pod jakimi nazwami dostępne są w linii komend, wpisuję:

m@mw:~$ apropos chrome
google-chrome (1)  - the web browser from Google
google-chrome-stable (1) - the web browser from Google
# podobnie dla chromium
m@mw:~$ apropos chromium
chromium-browser (1) - the web browser from Google
gyp (1)              - cross-platform makefile generator for Chromium

Skoro mamy już wiedzę o tym, jakie polecenie uruchomi Chrome/Chromium, możemy spróbować po raz pierwszy użyć ją w trybie niegraficznym. Przetestujmy to, próbując wygenerować plik PDF z przykładowej strony. Składnia polecenia wygląda tak:

m@mw:~$ google-chrome --headless --disable-gpu --print-to-pdf https://www.dwutygodnik.com/artykul/8162-podsumowanie-2018-roku.html

Kluczowym parametrem dodawanym do polecenia jest --headless, opcja --disable-gpu wyłącza wspomaganie sprzętowe (a właściwie pozwala obejść pewien błąd w programie, tutaj więcej na ten temat), --print-to-pdf wymusza wygenerowanie pliku PDF z podanym na końcu polecenia adresu URL. W bardzo podobny sposób wykonamy screenshot (do pliku *.png):

m@mw:~$ google-chrome --headless --disable-gpu --screenshot https://www.dwutygodnik.com/artykul/8162-podsumowanie-2018-roku.html

Jednak w ten sposób nie zawsze otrzymamy poprawny zrzut ekranu. W przypadku przykładowego linku z Dwutygodnika otrzymaliśmy tylko pierwszy widok (część) strony. Spróbujmy zmienić rozmiar ekranu:

m@mw:~$ google-chrome --headless --disable-gpu --screenshot --window-size=1280,1696 https://www.dwutygodnik.com/artykul/8162-podsumowanie-2018-roku.html

Treść jest już bardziej widoczna, jednak wciąż nie jest to cała strona. Aby z pomocą headless Chrome skutecznie wykonać pełny zrzut ekranu potrzeba niestety nieco więcej zachodu. Zostawmy to może i przejdźmy do ciekawszych zastosowań takiego typu pracy z przeglądarką.

Ukryte źródło

Niektóre strony, serwisy i platformy WWW budowane są dziś w taki sposób, że za renderowanie treści w przeglądarce odpowiadają nie tyle działające po stronie serwera skrypty, ale sama przeglądarka użytkownika i działający w niej język JavaScript. Przykładowo, jeżeli wejdziemy na stronę główną Polony i podejrzymy jej źródło (w Chrome wpisujemy adres view-source:https://polona.pl/), to kod źródłowy okaże się zdecydowanie zbyt krótki jak na ilość i rodzaj treści widocznej na stronie. Dzieje się tak dlatego, że (w dużym skrócie) poszczególne elementy strony dogrywane są dynamicznie do przeglądarki za pomocą JavaScriptu. Oznacza to, że JavaScript i działająca w trybie graficznym przeglądarka jest niezbędna do prawidłowego zrenderowania tej strony i odczytania jej pełnej treści.

Pozornie nie jest to żaden kłopot, w końcu na co dzień w taki sposób przeglądamy strony. Gdybyśmy jednak chcieli je masowo pobrać albo wyodrębnić z nich wybrane elementy DOM, nasza praca mogłaby się nie powieść. Jeśli wykorzystywany do pobierania czy przetwarzania treści program nie obsługuje JavaScriptu, pobierzemy jedynie szczątkowy kod źródłowy. Oto przykład z Polony porównujący objętość kodu źródłowego strony głównej, pobranego bez i ze wsparciem wykonywania kodu JavaScript:

  • Pobranie strony metodą wget (bez JS): 3 422 bajty
  • Pobranie z wykorzystaniem headless Chrome (z renderowaniem JS): 146 617 bajtów

Niestety część crawlerów czy scraperów nie będzie obsługiwać JavaScriptu i w efekcie pełna treść strony nie zostanie zrenderowana i skopiowana. Headless Chrome pozwala uniknąć tego błędu i programowo pobierać/przetwarzać renderowane w tle strony. Polecenie, które pozwala na wygenerowanie, ściągnięcie i zapisanie kodu takiej strony wygląda np. tak (dodajemy parametr --dump-dom, bo w rzeczywistości po prostu zrzucamy cały DOM do pliku):

m@mw:~$ google-chrome --headless --disable-gpu --dump-dom https://polona.pl/ > index.html

Oczywiście nie ma tu mowy o pobraniu pełnej strony (kod HTML/JavaScript, szablony stylów, grafika itp.) – ale do niektórych celów to wystarczy. Dynamicznie wyrenderowane źródło może być przeszukiwanie dalej pod kątem linków, adresów URL plików graficznych itp.

W praktyce przeglądarki w trybie headless wykorzystywane są w crawlerach i scraperach. Headless Chrome Crawler bez problemu renderuje strony bazujące na JavaScripcie i pozwala na zaawansowane zaprogramowanie crawlera. Dla języka R pakiet RSelenium pozwala łatwo przetwarzać dynamicznie generowane strony (w tym programowo wypełniać formularze, logować się itp.), a na dodatek daje możliwość wyboru przeglądarki – nie jesteśmy ograniczeni do Chrome czy Chromium.

Listę alternatywnych narzędzi bazujących na koncepcji headless browsing można znaleźć w tym artykule na Wikipedii.

Alexander the Great encounters the blemmyae, BL, Royal 20 A V, 14th c.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Akceptowane są wyłącznie komentarze merytoryczne. Każdy komentarz podlega moderacji.

Udostępnij na Twitterze | Udostępnij na Facebooku

Przeczytaj także