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?