Professional Documents
Culture Documents
Nodejs Konzolna Aplikacija: Seminarski Rad
Nodejs Konzolna Aplikacija: Seminarski Rad
TUZLANSKI KANTON
EVROPSKI UNIVERZITET KALLOS TUZLA
TEHNIČKI FAKULTET
INŽENJERSKA INFORMATIKA
VIŠI PROGRAMSKI JEZICI
Seminarski rad:
Profesor: Student:
Doc.Dr. Adis Rahmanović Elvis Džebo, 066/17-INI
Tuzla, 2019
Sadržaj:
1. 3
2. 4
2.1 Arhitektura platforme 5
2.2 Threading 5
2.3 V8 6
3. 7
3.1 Lista headless browsera 8
4. 9
4.1 Puppeteer struktura 10
5. 12
5.1 Instalacija NPM menadžera paketa i NodeJS instalacija na linux sistem 12
5.2 Puppeteer instalacija i implementiranje 14
5.3 Konzolna aplikacija 14
6. 20
2
1. Uvod
3
2. NodeJS
1
Laurent Orsini (2013-11-07). "Što trebate znati o Node.js", Arhivirano iz originala na 2013-11-07.
Preuzeto 2016-01-22
2
"PHP 7 vs Node.js? They Can Be Partners, Not Competitors For a Developer!". Posjećeno 20 Juni
2019.
4
promovišući saradnika i kreatora npm Isaac Schluetera da upravlja projektom. U januaru 2014.
godine, Schlueter je objavio da će Timothy J. Fontaine voditi projekt. U decembru 2014, Fedor
Indutny je započeo io.js, fork Node.js. Zbog unutrašnjeg konflikta oko Joyentovog upravljanja,
io.js je stvoren kao otvorena alternativa upravljanja sa odvojenim tehničkim komitetom. Za
razliku od Node.js, autori su planirali da održavaju io.js najnovijim izdanjima Google V8
JavaScript mehanizma. U februaru 2015. godine najavljena je namjera formiranja neutralne
Node.js fondacije. Do juna 2015. godine, zajednice Node.js i io.js glasale su da rade zajedno u
okviru Node.js fondacije. U septembru 2015. godine, Node.js v0.12 i io.js v3.3 su ponovo
spojeni u Node v4.0. Ovo spajanje je dovelo V8 ES6 funkcije u Node.js i dugoročni ciklus
izdavanja podrške. Od 2016. godine web stranica io.js preporučuje da se programeri vrate u
Node.js i da se ne planiraju daljnja izdanja io.js zbog spajanja.
2.2 Threading
Node.js radi na jednoj petlji događaja, koristeći neblokirajuće I/O pozive, dozvoljavajući
mu da podrži desetine hiljada istovremenih veza bez da izazove troškove preklapanja konteksta
niti(thread-ova). Dizajn dijeljenja jedne niti među svim zahtjevima koji koriste uzorak
promatrača namijenjen je za izgradnju visoko konkurentnih aplikacija, gdje svaka funkcija koja
5
izvodi I/O mora koristiti povratni poziv . Da bi se prilagodio jednostrukoj petlji događaja,
Node.js koristi libuv biblioteku - koja, zauzvrat, koristi niz nitova fiksne veličine koji obrađuje
neke od ne-blokiranih asinhronih I/O operacija.
Fazni nit obrađuje izvršavanje paralelnih zadataka u Node.js. Glavni poziv funkcije niti
objavljuje zadatke u zajedničkom redu zadataka, čije niti u pool-u nit izvlače i izvršavaju.
Inherentno neblokirajuće sistemske funkcije kao što je umrežavanje pretvaraju u ne-blokirne
utore na strani kernela, dok inherentno blokiraju sistemske funkcije kao što su datotečni I/O
pokrenuti na način blokiranja na svojim vlastitim nitima. Kada nit u nizu niti završi zadatak, ona
obavještava glavnu nit o tome, koja se zauzvrat budi i izvršava registrirani povratni poziv.
Loša strana ovog jednostrukog pristupa je da Node.js ne dozvoljava vertikalno skaliranje
povećanjem broja CPU jezgara mašine na kojoj se izvodi bez korištenja dodatnog modula, kao
što je klaster, StrongLoop Process Manager ili pm2. Međutim, programeri mogu povećati zadani
broj niti u libuv nizu niti. Operativni sistem poslužitelja (OS) će vjerovatno distribuirati ove niti u
više jezgara. Još jedan problem je to što dugotrajna računanja i drugi zadaci vezani za CPU
zamrzavaju cijelu događajnu petlju do završetka.
2.3 V8
6
3. Headless browser
Headless browser je web pretraživač bez grafičkog korisničkog interfejsa. Oni obezbjeđuju
automatsku kontrolu web stranice u okruženju sličnom popularnim web pretraživačima, ali se
izvršavaju preko sučelja komandne linije ili pomoću mrežne komunikacije. Oni su posebno
korisni za testiranje web stranica jer mogu prikazati i razumjeti HTML na isti način kao što bi to
učinio preglednik, uključujući elemente stila kao što su izgled stranice, boja, odabir fonta i
izvršavanje JavaScripta i AJAX-a koji obično nisu dostupni za druge metode ispitivanja.
Headless browseri koriste se za:
● Testiranje automatizacije u modernim web aplikacijama .
● Pravljenje snimaka web stranica.
● Pokretanje automatiziranih testova za JavaScript biblioteke.
● Skidanje sadržaja sa web stranica
● Automatiziranje interakcije web stranica.
Google je 2009. godine izjavio da bi korištenje headless browsera moglo pomoći njihovom
indeksiranju sadržaja sa web stranica koje koriste AJAX. 3
Međutim, ovakvi web browseri mogu se koristiti i u zle namjere:
● Izvršavanje DDOS napada na web stranicama.
● Manipulacija i kontrola pojavljivanja oglasa.
● Automatizovanje web stranica na nepredviđene načine
3
"Official Google Webmaster Central Blog: A proposal for making AJAX crawlable". Official Google
Webmaster Central Blog.
7
3.1 Lista headless browsera
Ovo je lista preglednika koji pružaju potpunu ili skoro potpunu implementaciju bez glave.
● Google Chrome - od verzije 59 Chrome podržava režim bez glave u Linuxu, MacOS-u i
Windowsu.
● Režim Firefox - bez glave dostupan je na linuxu od verzije 55. Verzija 56 je dodala
podršku za režim bez glave u Windowsu i MacOS-u.
● PhantomJS - web preglednik bez glave koji koristi WebKit mehanizam za prikazivanje
web stranica i JavaScriptCore za izvršavanje skriptiranih testova. PhantomJS je prvobitno
razvila Ariya Hidayat 2010. godine i stekla je širok ekosistem razvoja. Međutim, projekat
je od tada arhiviran i više nije u aktivnom razvoju.
● HtmlUnit - preglednik bez glave koji je pisan u Javi. HtmlUnit koristi Rhino motor kako
bi pružio JavaScript i AJAX podršku, kao i djelomičnu sposobnost renderovanja.
● TrifleJS - bezglavi Internet Explorer skriptni pretraživač koji koristi Trident engine za
prikazivanje stranica i V8 JavaScript mehanizam za izvršavanje skriptiranih testova.
TrifleJS koristi isti API jezik kao PhantomJS i radi pomoću .NET WebBrowser objekta
za kontrolu bilo koje verzije IE instalirane na računaru.
● Splash - web preglednik bez glave sa HTTP API-jem, Lua skripting podrškom i
ugrađenim IPython (Jupyter) baziranim IDE-om. Splash je napisan u Pythonu i koristi
WebKit layout engine. Razvoj je počeo u ScrapingHub-u 2013; djelimično ga finansira
DARPA.
● SimpleBrowser - lagan, veoma sposoban, bezglavi web preglednik sa skriptualnim .NET
Framework API-jem. SimpleBrowser napisan u C #, podržava .NET Framework 4.0 i
Mono. U toku je rad na nadogradnji na .NET Framework 4.5 i .NET Standard 2.0.
8
4. Puppeteer
Puppeteer je NodeJS biblioteka koja obezbjeđuje API visokog nivoa za kontrolu Chrome-a ili
Chroma preko DevTools protokola . Puppeteer po standardnim postavkama radi bez grafičkog
interfejsa, ali može biti konfiguriran tako da radi sa potpunim grafičkim interfejsom sa Chrome
ili Chromium web browserom.
Većinu stvari koje se mogu uraditi ručno u pretraživaču mogu se obaviti koristeći
Puppeteer. Kao primjer, sljedećih par slučajeva:
● Generisanje snimke zaslona
● Generisanje PDF fajlova na osnovu posjećenih stranica stranica.
● Pretražite SPA (Single-Page Application) i pregled istih
● Generisanje predodređenog sadržaja (tj. "SSR" (Server-Side Rendering)).
● Automatizirajte slanje obrasca
● Testiranje korisničkog interfejsa, unos sa tastature itd.
Puppeteer se najviše koristi kao softwer kreiranje i automatiziranu okruženja za izvođenje
automatski testiranja. Puppeteer testove provodi direktno u najnovijoj verziji Chrome-a koristeći
najnovije JavaScript verzije.
Takođe Puppeteer se koristi i za testiranje performansi web stranica, te za uočavanje posteškoća
pri renderovanju.
U ovom specifičnom slučaju, Puppeteer se, ujedno sa NodeJS i još nekim bibliotekama koristi za
prikupljanje informacija sa određene stranice, te se ti podaci spremaju u MySql bazu podataka.
Daljnje korištenje prikupljenih podataka se neće razmatrati u ovom radu, jer bi se time narušio
odnos povjerenja između autora ovog rada i klijenta za koga je ova konzolna aplikacija izrađena.
9
4.1 Puppeteer struktura
Puppeteer je NodeJS biblioteka koja obezbeđuje API visokog nivoa za kontrolu Chrome-
a ili Chroma preko DevTools protokol, koja je hijerarhijski određena, te ima za mogućnost da u
potpunosti oponaša strukturu standardnog browsera(Slika 1).
10
Komunikacija se ostvaruje preko devTools protokola, razvijenog od strane developerskog tima
kompanije Google koja ujedno održava i V8 Google browser engine. Nakon što se Puppeteer
pokrene, moguće je ostvariti vise browserskih konteksta, koji u isto vrijeme mogu obavljati više
zadataka. Ispod browser konteksta, nalazi se sloj stranica, koje takođe mogu imati višestruke
uloge i simultano izvršavati pozive u zasebnim sklopovima sa jednom browser sesijom. Svaka
stranica (eng. page), ima jedan osnovni okvir (eng. frame), a unutar njega može postojati više
okvira koji odgovaraju na pozive glavnog okvira stranice. Na primjer, izvršavanje javascript
koda na web stranici koji zahtjeva otvaranje neko skočnog prozora.
API protokol je zasnovan na najnovijim verzijama NodeJS (Javascript) jezika, te u skladu
s tim, svaki poziv funkcije u Puppeteer kontekstu, posmatra se kao asinhroni poziv, a razrješenje
svake funkcije, ima za rezultat “Promise” koji će se u jednom određenom trenutku odazvati ili
neće, tako da nema treće verzije. Takođe, Puppeteer koristi neblokirajuće asinhrone pozive
(stručnog naziva async/await, ECMAScript notacija), što omogućava jednostavno pisanje i
održavanje koda tokom razvijanja aplikacije.
11
5. Primjer konzolne aplikacije
U nastavku ovog rada, bit će predstavljen proces razvijanja ranije spomenute konzolne
aplikacije sa slikama i objašnjenjima.
12
Node.js je platforma izgrađena na Chrome-ovom JavaScript runtime-u za lako stvaranje
brzih, skalabilnih mrežnih aplikacija. Najnovij verzija node.js održava se na svom zvaničnom
sajtu.
Nakon instalacije, trenutna verzija NodeJS i NPM se može provjeriti da se uvjeri da je instalacija
prošla bez problema:
“$ node --version”
“$ npm --version”
Ove komande će generisati sljedeći izlaz u terminalu:
13
Slika 3. Izlaz nakon instalacije NodeJS i NPM
14
Potrebno je kreirati novi fajl, proizvoljnog imena sa extenzijom .js. Prva linija koda je
deklarisanje puppeteer headless browsera, te dodatnih biblioteka, mysql konektora, fs
(FileSystem) biblioteke za lakši zapis podataka u fajl (Slika 4).
Nakon toga, potrebno je pozvati puppeteer browser unutar asinhrone funkcije, da bi se mogli
čekati rezultati prethodno definisanih Promise metoda.
15
Slika 5. Instanciranje browser-a i parametri pri pokretanju
Linija 33 definiše asinhronu funkciju i kao glavni argument poziva instancu browsera. Na liniji
36, browser je definisan i u pozadini spreman za rad.
Linije koda 37 do 46 šalju puppeteer dodatne argumente koje će se koristiti u radu:
● '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-
usage' - Bez sigurnosnih ograničenja, dopušta se browseru da koristi resurse računara i
sistema
● '--disable-gpu',--disable-accelerated-2d-canvas', - Pokretanje instance
browsera bez grafičkog interfejsa
● '--window-size=1920x1080' - Veličina prozora koja se koristi prilikom pokretanja
16
Slika 6. Dohvatanje potrebnih podataka sa web stranice
Na slici 6. nalazi se glavni dio aplikacije, koji dohvata potrebne podatke sa određenih web
stranica.
Linija 47 postavlja određeni string u browser, na mjesto posebno predefinisanog polja “User
Agent” kako bi web stranica znala kako i na koji način da posluzi HTML kod i ostale potrebne
dijelove.
Linija 51, dio koda “await page.goto(https://www.nekilink.com)” usmjerava ranije
pokrenuti web pretraživač na određenu web adresu. “Await” je dio ES6 javascript strukture. Na
ovaj način se govori programu da pauzira i da “čeka” odgovor od strane poslužitelja web
stranice. Nakon određenog vremena dohvatit će se web stranica i kod će se nastaviti izvršavati.
Linija koda 52, je dodatni osigurač. Zbog toga sto je puppeteer automatiziran, često se desi da po
automatizmu on nastavi dalje, a Javascripti sa stranice je potrebno neko vrijeme da se izvrši. Da
bi se izbjegla ta preklapanja, često se koristi “.waitForSelector()” funkcija, koja čeka da se
određeni selektor DOM strukture pojavi i bude vidljiv ili u ovom slučaju, jednostavno
“waitFor()” funkcija, koja čeka zadani broj milisekundi prije nego nastavi dalje.
Prikupljanje podataka se vrši od linije 53 do 64. Puppeteer API sistem koristi HTML parsiranje,
skoro identično jQuery biblioteci, pa je upravljanje tekstom ili bilo kojim dijelom HTML
17
stranice, izuzetno pristupačno i lagano.
Nakon toga, svi objekti iz ranije definisanog niza se spremaju u bazu podataka. Parametri se
deklarišu na liniji 285. Kasnije, na liniji 287, kroz update query, ti podaci se šalju u bazu i
spremaju se za daljnje korištenje. Ukoliko se iz bilo kog razloga dogodi neka greška ili
neočekivano ponašanja, te izuzetke uslovno rečeno hvataju linije koda od 288 do 300. Greške će
se ispisati u konzoli ili u neki log fajl, ovisno o tome kako se programer odluči.
18
Slika 9. Zatvaranje browsera i sql konektora
Nakon svih izvršenih radnji, poziva se funkcija “close()” na nivou browsera koja zatvara sve
aktivne instance puppeteer biblioteke, čisti threadove i oslobađa memoriju. Naposlijetku, zatvara
se i konekcija prema bazi. Proces je uspješno završen i skripta je uspješno dohvatila potrebne
podatke.
Napominje se da je čitav proces u ovom radu pojednostavljen, a ukoliko je potrebno,
čitav source code aplikacije se može pogledati u dodatku ovom seminarskom radu.
19
6. Zaključak
Iako izuzetno sažeto, u ovom radu su predstavljene osnove NodeJS frameworka, Puppeteer
API biblioteke i osnovni načini programiranja skripti i aplikacija za dohvatanje podataka.
Puppeteer sam po sebi je predviđen za mnogo različitih namjena, a jedna od njih je opisana u
ovom radu. Prilikom korištenja Puppeteer-a, potrebno je biti i oprezan. Samim tim sto je uz
pomoć ovakve tehnologije izgenerisati dosta posjeta jednoj web stranici, moguće je i web server
zagušiti zahtjevima. Potrebno je držati se etike i ne narušiti normalan rad posjećenog web sajta.
Takođe, ovakvo ponašanje je kažnjivo i zakonom te podliježe krivičnom gonjenju u većini
zemalja svijeta. Na kraju, sve je u rukama onoga ko pravi aplikaciju, a u skladu s tim, sve
posljedice i benefiti idu u njegovu korist.
20
Literatura
21