Dzisiejsze strony internetowe bardzo często ładują lub modyfikują treść przy użyciu JavaScript. Korzystając z „gołego” PHP czy Pythona niemożliwe jest pobranie takiej treści. Z pomocą przychodzi Headless Chrome.
Jako programista, specjalista SEO czy zwyczajny użytkownik, pewnie nie raz potrzebowałeś pobrać dane ze strony ale pojawiał się jeden, główny problem: ręcznie trwałoby to zbyt długo. Napisałeś/zleciłeś napisanie crawlera/scrapera, który te dane pobierze. OK działa. Co jednak ze stronami internetowymi czy aplikacjami, które ładują dodatkową treść przy scrolowaniu strony, odświeżaniu gdy dodasz nowy wpis itd.? Możemy wykorzystać Headless Chrome (https://developers.google.com/web/updates/2017/04/headless-chrome), renderować stronę tak jak widzimy ją na co dzień i pobierać zawartość strony, modyfikować ją, a także symulować użytkownika.
Pomysłów na wykorzystanie tego będzie wiele – w zależności czego potrzebujesz w konkretnej chwili. Kilka z nich:
- bot, który wykonuje powtarzalne czynności
- zbieranie informacji ze strony, np. pobranie tytułów artykułów (co zobaczycie w przykładzie)
- pobieranie adresów e-mail
- symulowanie zachowania użytkownika na stronie
Dość „gadania” – zaczynamy!
Napiszemy bota, który odwiedzi stronę napisaną w JavaScript (wappalyzer pokazuje, że napisana jest przy użyciu React) i pobierze tytuły widoczne po załadowaniu strony .
- Zainstaluj nodejs na swoim komputerze: https://nodejs.org
- Utwórz katalog w którym będziesz przechowywał pliki projektu
- Otwórz terminal i przejdź do utworzonego katalogu. Wykonaj następujące polecenia
- npm i puppeteer (https://github.com/GoogleChrome/puppeteer)
- npm i cheerio (https://github.com/cheeriojs/cheerio)
- Utwórz plik, np. crawler.js
- Otwórz IDE lub dowolny edytor, np. Atom (https://atom.io)
- Wklej poniższy kod do edytora i zapisz pod dowolna nazwą, np. crawler.js
const puppeteer = require('puppeteer');
const cheerio = require('cheerio');
const URL = 'https://www.reddit.com';
const FILENAME = 'reddit_screenshot.png';
async function run() {
// headless: false - chcemy widzieć okno otwieranej przeglądarki
// headless: true - przeglądarka działa w tle
// disable-notifications - blokujemy w przeglądarce pytanie o możliwość pokazywania powiadomień
const browser = await puppeteer.launch({headless: false, args: ["--disable-notifications"]});
const page = await browser.newPage();
// ustawia rozdzielczość ekranu
await page.setViewport({width: 1920, height: 1080});
// przechodzi pod podaną stronę
await page.goto(URL);
// wykonuje screenshot
await page.screenshot({path: FILENAME});
let content = await page.content();
let $ = cheerio.load(content);
$('h3').each(function (i, e) {
// wyświetla wszystkie tytuły w H3 w terminalu
console.log($(this).text());
});
browser.close();
}
run();
Kod:
W terminalu wykonaj polecenie
node crawler.js
Efekt?
Zobaczysz otwierające się okno, które po chwili zamknie się. W konsoli zobaczysz tytuły artykułów, a w katalogu projektu zostanie utworzony plik (screenshot) strony internetowej, którą odwiedziliśmy – reddit.com.
Podsumowanie
Jak widzisz, napisanie własnego crawlera może ułatwić Tobie pracę. Oczywiście musisz zdecydować co „opłaca się” bardziej, ponieważ może okazać się, że poświęcisz więcej czasu na napisanie własnego scrapera niż wyciąganie danych ręcznie ale… gdy możesz go wykorzystać kilkukrotnie – na pewno przyda się a Ty w tym czasie możesz wykonywać inne rzeczy.
Jeśli masz inne pomysły na wykorzystanie takiego crawlera – napisz w komentarzu 🙂
Zastanawiam się czy nie dało by się tego samego zrobić przy pomocy lighthouse od google. Dodatkowo mielibyśmy dużo więcej informacji typu TTFB
Nie wiem czy możliwe jest (przy pomocy lighthouse) crawlowanie i zbieranie dodatkowych danych które wskażemy, np. tytuły wpisów, linki, maile, symulowanie zachowania użytkownika.
Dzięki podsunięcie tematu lighthouse – nie wiedziałem, że można wykorzystać ten moduł w nodejs 🙂
Ciekawe podejście do tematu 🙂
Dzięki za wpis!
A jednak Javascript ma więcej możliwości niż myślałem 🙂 Dzięki za info – na pewno się przyda.
Mi podoba się taki bot, ale czy to faktycznie takie proste, żeby w kilku liniach kodu napisać dobrego i wydajnego bota? Domyślam się, że napisanie takiego co zbiera i zapisuje gdzieś dane z analizy, robi to co jakiś czas, wchodzi w inne url na jakie trafi itp. to już inna bajka.
Wpis z przed kilku miesięcy, ale wpadłem na super pomysł dzięki Tobie:)) dzisiaj startuje z projekcikiem. Kod bardzo krótki i będzie testowany, ciekawe czy mi się uda. Oczywiście można to bardzo fajnie rozbudować i zrobić w pełni przydatna apke, ale to już przyszłość.
Powodzenia! Pochwal się rezultatem 🙂