Začínáme s škrábáním webu v JavaScriptu

Web scraping, neboli dolování dat z webových stránek, se řadí mezi fascinující oblasti programování.

Co vlastně tento proces obnáší?

Jaký je jeho smysl?

Pojďme se společně ponořit do odpovědí.

Základní principy web scrapingu

Web scraping je automatizovaná metoda, která umožňuje získávat informace z webových stránek.

Využití této techniky je rozmanité. Můžeme například extrahovat ceny produktů a porovnávat je na různých e-commerce platformách, získávat denní nabídky ze specializovaných webů nebo dokonce vytvářet vlastní vyhledávače, které konkurují gigantům jako Google či Yahoo. Možnosti jsou téměř neomezené.

Web scraping otevírá dveře k mnoha dalším aktivitám. Jakmile zvládnete principy extrakce dat z webu, máte volnou ruku k jejich dalšímu zpracování dle vašich potřeb.

Program, který provádí extrakci dat, se nazývá web scraper. V následujícím textu si ukážeme, jak vytvářet takové nástroje pomocí JavaScriptu.

Proces web scrapingu se skládá ze dvou hlavních kroků:

  • Získání surových dat z webových stránek za pomoci knihoven pro HTTP požadavky a bezhlavých prohlížečů.
  • Analýza získaných dat s cílem extrahovat přesně ty informace, které jsou pro nás relevantní.

Bez zbytečného otálení se můžeme pustit do práce.

Příprava vývojového prostředí

Předpokládá se, že máte nainstalované prostředí Node.js. V případě, že tomu tak není, navštivte oficiální stránky projektu a postupujte dle instrukcí pro instalaci.

Pro web scraping v JavaScriptu využijeme balíčky `node-fetch` a `cheerio`. Pro správu závislostí budeme používat npm.

Následující kroky vás provedou přípravou vývojového prostředí:

  • Vytvořte nový adresář s názvem `web_scraping` a přejděte do něj.
  • Inicializujte projekt pomocí příkazu `npm init`.
  • Odpovězte na otázky inicializačního průvodce dle vašich preferencí.
  • Nainstalujte potřebné balíčky pomocí příkazu:
npm install node-fetch cheerio

Nyní si krátce představíme nainstalované balíčky.

`node-fetch`

Balíček `node-fetch` přináší funkčnost `window.fetch` do prostředí Node.js. Umožňuje vytvářet HTTP požadavky a získávat surová data.

`cheerio`

Balíček `cheerio` slouží k parsování a extrakci konkrétních informací ze získaných surových dat.

Pro web scraping v JavaScriptu nám balíčky `node-fetch` a `cheerio` bohatě postačí. Neprobereme si detailně všechny metody, které tyto balíčky nabízejí, zaměříme se spíše na pracovní postup a nejužitečnější metody v rámci tohoto procesu.

Na konci tohoto průvodce byste měli ovládat základy web scrapingu. Pojďme tedy začít.

Extrakce dat o Mistrovství světa v kriketu

V této části se pustíme do praktické ukázky web scrapingu.

Co konkrétně budeme dolovat?

Jak napovídá název sekce, budeme se zabývat extrakcí seznamu vítězů Mistrovství světa v kriketu z webu.

  • Vytvořte v projektu soubor s názvem `extract_cricket_world_cups_list.js`.
  • Pro získání požadovaných informací využijeme stránku Mistrovství světa v kriketu na Wikipedii.
  • Nejprve si za pomoci balíčku `node-fetch` zajistíme surová data.
  • Následující kód získá surová data z výše uvedené webové stránky:
const fetch = require("node-fetch");

// Funkce pro získání surových dat
const getRawData = (URL) => {
   return fetch(URL)
      .then((response) => response.text())
      .then((data) => {
         return data;
      });
};

// URL s daty
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";

// Spuštění programu
const getCricketWorldCupsList = async () => {
   const cricketWorldCupRawData = await getRawData(URL);
   console.log(cricketWorldCupRawData);
};

// Vyvolání hlavní funkce
getCricketWorldCupsList();

Surová data z URL jsme úspěšně získali. Nyní přichází čas na extrakci potřebných informací. Pro tento účel využijeme balíček `cheerio`.

Zpracování dat obsahujících HTML tagy pomocí `cheerio` je velmi snadné. Než se pustíme do zpracování reálných dat, podívejme se na několik ilustračních příkladů:

  • Načtěte HTML data pomocí metody `cheerio.load`.
const parsedSampleData = cheerio.load(
      `<div id="container"><p id="title">Toto je nadpis</p></div>`
   );
  • Data jsme úspěšně naparsovali. Jak nyní získáme obsah tagu `p`? Stejně jako u selektorů v JavaScript DOM.

console.log(parsedSampleData(„#title“).text());

Tagy můžete vybírat podle libosti. Další metody naleznete na oficiálních stránkách `cheerio`.

  • Nyní můžeme přistoupit k získání seznamu vítězů Mistrovství světa. Abychom mohli data extrahovat, musíme znát HTML tagy, ve kterých jsou informace uloženy. Navštivte stránku Mistrovství světa v kriketu na Wikipedii a prozkoumejte zdrojový kód stránky.

Níže naleznete kompletní kód.

const fetch = require("node-fetch");
const cheerio = require("cheerio");

// Funkce pro získání surových dat
const getRawData = (URL) => {
   return fetch(URL)
      .then((response) => response.text())
      .then((data) => {
         return data;
      });
};

// URL s daty
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";

// Spuštění programu
const getCricketWorldCupsList = async () => {
   const cricketWorldCupRawData = await getRawData(URL);

   // Parsrování dat
   const parsedCricketWorldCupData = cheerio.load(cricketWorldCupRawData);

   // Extrakce dat z tabulky
   const worldCupsDataTable = parsedCricketWorldCupData("table.wikitable")[0]
      .children[1].children;

   console.log("Rok --- Vítěz --- Finalista");
   worldCupsDataTable.forEach((row) => {
      // Extrakce tagů `td`
      if (row.name === "tr") {
         let year = null,
            winner = null,
            runner = null;

         const columns = row.children.filter((column) => column.name === "td");

         // Extrakce roku
         const yearColumn = columns[0];
         if (yearColumn) {
            year = yearColumn.children[0];
            if (year) {
               year = year.children[0].data;
            }
         }

         // Extrakce vítěze
         const winnerColumn = columns[3];
         if (winnerColumn) {
            winner = winnerColumn.children[1];
            if (winner) {
               winner = winner.children[0].data;
            }
         }

         // Extrakce finalisty
         const runnerColumn = columns[5];
         if (runnerColumn) {
            runner = runnerColumn.children[1];
            if (runner) {
               runner = runner.children[0].data;
            }
         }

         if (year && winner && runner) {
            console.log(`${year} --- ${winner} --- ${runner}`);
         }
      }
   });
};

// Vyvolání hlavní funkce
getCricketWorldCupsList();

A zde jsou extrahovaná data:

Rok --- Vítěz --- Finalista
1975 --- West Indies --- Australia
1979 --- West Indies --- England
1983 --- India --- West Indies
1987 --- Australia --- England
1992 --- Pakistan --- England
1996 --- Sri Lanka --- Australia
1999 --- Australia --- Pakistan
2003 --- Australia --- India
2007 --- Australia --- Sri Lanka
2011 --- India --- Sri Lanka
2015 --- Australia --- New Zealand
2019 --- England --- New Zealand

Skvělé, že?

Šablona pro web scraping

Získávání surových dat z URL je běžný krok v každém projektu web scrapingu. Jediná věc, která se mění, je extrakce dat podle konkrétního požadavku. Následující kód si můžete uložit a používat jako šablonu:

const fetch = require("node-fetch");
const cheerio = require("cheerio");
const fs = require("fs");
// Funkce pro získání surových dat
const getRawData = (URL) => {
   return fetch(URL)
      .then((response) => response.text())
      .then((data) => {
         return data;
      });
};
// URL s daty
const URL = "https://example.com/";
// Spuštění programu
const scrapeData = async () => {
   const rawData = await getRawData(URL);
   // Parsrování dat
   const parsedData = cheerio.load(rawData);
   console.log(parsedData);
   // Zde vložte kód pro extrakci dat
   // ...
   // ...
};
// Vyvolání hlavní funkce
scrapeData();

Závěr

Nyní již víte, jak extrahovat data z webových stránek. Další rozvoj vašich dovedností je již jen na vás. Doporučuji vám vyzkoušet si i jiné, pokročilejší frameworky pro web scraping a podívat se také na cloudová řešení.

Přeji vám mnoho úspěchů při programování 🙂

Líbil se vám tento článek? Neváhejte jej sdílet s ostatními.