Почетак рада са Веб Сцрапинг-ом у ЈаваСцрипт-у

Web scraping, odnosno struganje veba, predstavlja jednu od najfascinantnijih oblasti u svetu programiranja.

Ali, šta tačno podrazumevamo pod pojmom web scraping?

I zašto uopšte postoji takva praksa?

Hajde da zajedno istražimo odgovore na ova pitanja.

Šta je Web Scraping?

Web scraping je automatizovan proces prikupljanja podataka sa različitih web stranica.

Postoji veliki broj primena za web scraping. Možemo, na primer, izdvojiti cene proizvoda i upoređivati ih na različitim platformama za e-trgovinu. Takođe, možemo pribavljati dnevne ponude sa raznih web lokacija ili čak kreirati sopstveni pretraživač, poput Google-a ili Yahoo-a. Lista mogućnosti je zaista duga.

Mogućnosti web scraping-a su zaista obimne. Kada jednom savladate veštinu izvlačenja podataka sa web stranica, otvara se čitav niz mogućnosti za manipulaciju i analizu tih podataka.

Program koji vrši izvlačenje podataka sa web lokacija naziva se web scraper. U ovom vodiču, naučićemo kako da pišemo web scrapere koristeći JavaScript.

Generalno, proces web scraping-a se sastoji iz dva glavna dela:

  • Pribavljanje podataka korišćenjem biblioteka za slanje zahteva i pretraživača bez grafičkog interfejsa (headless browsers).
  • Parsiranje podataka kako bismo iz njih izdvojili one informacije koje su nam relevantne.

Bez daljeg odlaganja, krenimo na posao!

Priprema Projekta

Pretpostavićemo da imate instaliran Node.js. Ukoliko nemate, pogledajte neki vodič za instalaciju Node.js.

Za web scraping u JavaScript-u, koristićemo pakete `node-fetch` i `cheerio`. Prvo ćemo podesiti projekat koristeći npm kako bismo mogli da radimo sa eksternim paketima.

Pogledajmo korake neophodne za pripremu našeg projekta:

  • Kreirajte novi direktorijum pod nazivom `web_scraping` i pređite u njega.
  • Pokrenite komandu `npm init` kako biste inicijalizovali projekat.
  • Odgovorite na sva pitanja koja se pojave u skladu sa vašim preferencijama.
  • Sada instalirajte potrebne pakete pomoću komande:
npm install node-fetch cheerio

Hajde da se upoznamo sa instaliranim paketima.

node-fetch

Paket `node-fetch` donosi funkcionalnost `window.fetch` u Node.js okruženje. On omogućava slanje HTTP zahteva i pribavljanje sirovih podataka.

cheerio

Paket cheerio služi za parsiranje i izdvajanje relevantnih informacija iz sirovih podataka.

Kombinacija paketa `node-fetch` i `cheerio` je dovoljna za web scraping u JavaScript-u. Nećemo detaljno prolaziti kroz sve metode koje ovi paketi nude, već ćemo se fokusirati na sam proces struganja i najkorisnije metode u tom kontekstu.

Na ovaj način, steći ćete praktično znanje o web scrapingu. Dakle, krenimo na konkretne zadatke.

Struganje Liste Svetskih Prvenstava u Kriketu

U ovom delu ćemo sprovesti pravi proces web scraping-a.

Šta ćemo tačno izvlačiti?

Prema naslovu ovog dela, verujem da ćete lako pogoditi. Tako je, izvlačićemo listu svih dosadašnjih pobednika i drugoplasiranih na Svetskim prvenstvima u kriketu.

  • Napravite novu datoteku pod nazivom `extract_cricket_world_cups_list.js` u okviru vašeg projekta.
  • Koristićemo Vikipedija stranicu o Svetskom prvenstvu u kriketu kao izvor informacija.
  • Prvo, pribavićemo sirove podatke koristeći paket `node-fetch`.
  • Sledeći kod pribavlja sirove podatke sa pomenute Vikipedija stranice:
const fetch = require("node-fetch");

// funkcija za pribavljanje sirovih podataka
const getRawData = (URL) => {
    return fetch(URL)
        .then((response) => response.text())
        .then((data) => {
            return data;
        });
};

// URL za podatke
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";

// početak programa
const getCricketWorldCupsList = async () => {
    const cricketWorldCupRawData = await getRawData(URL);
    console.log(cricketWorldCupRawData);
};

// pozivanje glavne funkcije
getCricketWorldCupsList();

Sada kada imamo sirove podatke, vreme je da iz njih izdvojimo one informacije koje su nam potrebne. Koristićemo paket `cheerio` za ovu svrhu.

Izdvajanje podataka, uključujući HTML tagove, pomoću paketa `cheerio` je prilično jednostavno. Pre nego što pređemo na konkretne podatke, pogledajmo neke primere parsiranja podataka pomoću `cheerio`:

  • Parsirajte HTML podatke koristeći metodu `cheerio.load`.
const parsedSampleData = cheerio.load(
      `<div id="container"><p id="title">Ja sam naslov</p></div>`
  );
  • Upravo smo parsirali gornji HTML kod. Kako da izvučemo sadržaj `p` taga? Princip je sličan selektorima u JavaScript DOM manipulaciji.

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

Možete selektovati tagove na različite načine. Više informacija možete naći na zvaničnoj stranici paketa cheerio.

  • Sada je vreme da izvučemo listu Svetskih prvenstava. Da bismo izdvojili informacije, moramo znati HTML tagove koji se nalaze na stranici. Posetite stranicu Vikipedije o Svetskom prvenstvu u kriketu i pregledajte elemente da biste saznali više o HTML tagovima.

Sledi kompletan kod:

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

// funkcija za pribavljanje sirovih podataka
const getRawData = (URL) => {
    return fetch(URL)
        .then((response) => response.text())
        .then((data) => {
            return data;
        });
};

// URL za podatke
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";

// početak programa
const getCricketWorldCupsList = async () => {
    const cricketWorldCupRawData = await getRawData(URL);

    // parsiranje podataka
    const parsedCricketWorldCupData = cheerio.load(cricketWorldCupRawData);

    // izdvajanje podataka iz tabele
    const worldCupsDataTable = parsedCricketWorldCupData("table.wikitable")[0]
        .children[1].children;

    console.log("Godina --- Pobednik --- Drugoplasirani");
    worldCupsDataTable.forEach((row) => {
        // izdvajanje `td` tagova
        if (row.name === "tr") {
            let year = null,
                winner = null,
                runner = null;

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

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

            // izdvajanje pobednika
            const winnerColumn = columns[3];
            if (winnerColumn) {
                winner = winnerColumn.children[1];
                if (winner) {
                    winner = winner.children[0].data;
                }
            }

            // izdvajanje drugoplasiranog
            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}`);
            }
        }
    });
};

// pozivanje glavne funkcije
getCricketWorldCupsList();

A ovo su izdvojeni podaci:

Godina --- Pobednik --- Drugoplasirani
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

Super, zar ne? 😎

Šablon za Scraping

Pribavljanje sirovih podataka sa URL adrese je zajednički deo svakog projekta web scraping-a. Jedini deo koji se menja je izdvajanje podataka prema zahtevu. Možete isprobati sledeći kod kao šablon:

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

// funkcija za pribavljanje sirovih podataka
const getRawData = (URL) => {
    return fetch(URL)
        .then((response) => response.text())
        .then((data) => {
            return data;
        });
};

// URL za podatke
const URL = "https://example.com/";

// početak programa
const scrapeData = async () => {
    const rawData = await getRawData(URL);
    // parsiranje podataka
    const parsedData = cheerio.load(rawData);
    console.log(parsedData);
    // ovde pišite kod za izdvajanje podataka
    // ...
    // ...
};

// pozivanje glavne funkcije
scrapeData();

Zaključak

Naučili ste kako da „stružete“ web stranice. Sada je red na vas da vežbate kodiranje.

Takođe bih predložio da istražite popularne okvire za web scraping, kao i rešenja za web scraping zasnovana na cloudu.

Srećno kodiranje 🙂

Da li vam se dopao ovaj članak? Šta kažete da ga podelite sa svetom?