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

You May Also Like

About the Author: Mateusz Dudek

7 Comments

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

    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 🙂

  2. A jednak Javascript ma więcej możliwości niż myślałem 🙂 Dzięki za info – na pewno się przyda.

  3. 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.

  4. 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ść.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *