Crawler, scraper stron internetowych napisanych w JavaScript? Przykład

javascript crawler scraper

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 .

  1. Zainstaluj nodejs na swoim komputerze: https://nodejs.org
  2. Utwórz katalog w którym będziesz przechowywał pliki projektu
  3. Otwórz terminal i przejdź do utworzonego katalogu. Wykonaj następujące polecenia
    1. npm i puppeteer (https://github.com/GoogleChrome/puppeteer)
    2. npm i cheerio (https://github.com/cheeriojs/cheerio)
  4. Utwórz plik, np. crawler.js
  5. Otwórz IDE lub dowolny edytor, np. Atom (https://atom.io)
  6. Wklej poniższy kod do edytora i zapisz pod dowolna nazwą, np. crawler.js

Kod:

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();

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 🙂

[Głosów:4    Średnia:4/5]

You May Also Like

About the Author: Mateusz Dudek

3 Comments

    1. 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 🙂

Dodaj komentarz

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