Klijentsko struganje weba s JavaScriptom pomoću jQuery i Regex

Kad sam gradio svoj prvi projekt otvorenog koda, codeBadges, mislio sam da će biti lako dobiti podatke o korisničkom profilu sa svih glavnih web stranica za učenje koda.

Bio sam upoznat s API pozivima i primanjem zahtjeva. Mislio sam da bih jednostavno mogao koristiti jQuery za dohvaćanje podataka s različitih API-ja i njihovo korištenje.

var name = 'codemzy'; $.get('//api.github.com/users/' + name, function(response) { var followers = response.followers;});

Pa, to je bilo lako. No, ispostavilo se da nema svaka web stranica javni API za koji možete jednostavno zgrabiti podatke od kojih želite.

Ali to što ne postoji javni API ne znači da trebate odustati! Za prikupljanje podataka možete koristiti struganje putem interneta, uz samo malo dodatnog rada .

Pogledajmo kako možemo koristiti struganje weba na strani klijenta s JavaScriptom.

Na primjer, prikupit ću svoje korisničke podatke s mog javnog profila freeCodeCamp. Ali ove korake možete koristiti na bilo kojoj javnoj HTML stranici.

Prvi korak u struganju podataka je hvatanje cijele stranice html pomoću jQuery .getzahtjeva.

var name = "codemzy";$.get('//www.freecodecamp.com/' + name, function(response) { console.log(response);});

Sjajno, izvorni kod cijele stranice upravo se prijavio na konzolu.

Napomena: Ako u ovoj fazi dobijete pogrešku poput No ‘Access-Control-Allow-Origin’ header is present on the requested resourcenemoj se uzrujavati. Pomaknite se dolje do odjeljka Ne dopusti da vas CORS zaustavi u ovom postu.

To je bilo lako. Koristeći JavaScript i jQuery, gornji kod zahtijeva stranicu s www.freecodecamp.org, kao što to traži preglednik. I freeCodeCamp odgovara stranicom. Umjesto da preglednik pokreće kôd za prikaz stranice, dobivamo HTML kôd.

I to je ono što je struganje weba, vađenje podataka s web stranica.

Ok, odgovor nije baš tako uredan kao podaci koje dobivamo natrag iz API-ja.

Ali ... mi imamo podatke, tu negdje.

Jednom kad imamo izvorni kod, tamo su potrebne informacije koje trebamo, samo moramo prikupiti podatke koji su nam potrebni!

Možemo pretražiti odgovor kako bismo pronašli elemente koji su nam potrebni.

Recimo da želimo znati koliko je izazova korisnik završio, iz odgovora korisničkog profila koji smo dobili natrag.

U vrijeme pisanja ovog članka, završeni izazovi kampera organizirani su u tablice na korisničkom profilu. Dakle, da bismo dobili ukupan broj dovršenih izazova, možemo izbrojati broj redaka.

Jedan od načina je zamotati čitav odgovor u jQuery objekt, tako da možemo koristiti jQuery metode poput .find()dobivanja podataka.

// number of challenges completedvar challenges = $(response).find('tbody tr').length;

Ovo dobro funkcionira - postižemo pravi rezultat. Ali to nije dobar način za postizanje rezultata za kojim tragamo. Pretvaranje odgovora u jQuery objekt zapravo učitava cijelu stranicu, uključujući sve vanjske skripte, fontove i tablice stilova s ​​te stranice ... Uh!

Trebamo nekoliko bitova podataka. Stvarno nam nije potrebno učitavanje stranice, a zasigurno nisu svi vanjski resursi koji dolaze s njom.

Mogli bismo ukloniti oznake skripte, a zatim pokrenuti ostatak odgovora kroz jQuery. Da bismo to učinili, mogli bismo upotrijebiti Regex kako bismo u tekstu tražili uzorke skripti i uklonili ih.

Ili još bolje, zašto ne bismo upotrijebili Regex da pronađemo ono što prvo tražimo?

// number of challenges completedvar challenges = response.replace(/[\s|\S]*?/g).match(//g).length;

I djeluje! Korištenjem gornjeg Regex koda uklanjamo retke glave tablice (koji nisu sadržavali izazove), a zatim podudaramo sve retke tablice kako bismo prebrojali broj dovršenih izazova.

Još je lakše ako su željeni podaci samo tamo u odgovoru u običnom tekstu. U vrijeme pisanja korisničkih bodova bili su u html-u

[ 1498 ]

samo čeka da me ostružu.

var points = response.match(/

\[ ([\d]*?) \]/)[1];

U gornjem uzorku Regex-a podudaramo se s elementom h1 koji tražimo, uključujući onaj [ ]koji okružuje točke, i grupiramo bilo koji broj unutar pomoću. ([\d]*?).Vraćamo niz, prvi [0]element je cijelo poklapanje, a drugi [1]je podudaranje naše grupe ).

Regex je koristan za podudaranje svih vrsta uzoraka u nizovima, a odličan je i za pretragu kroz naš odgovor kako bismo dobili podatke koji su nam potrebni.

Isti postupak u tri koraka možete koristiti za struganje podataka profila s raznih web lokacija:

  1. Koristite JavaScript na strani klijenta
  2. Koristite jQuery za struganje podataka
  3. Koristite regularni izraz za filtriranje podataka za relevantne informacije

Dok nisam naišao na problem, CORS.

Ne dopustite da vas CORS zaustavi!

CORS ili dijeljenje resursa više izvora mogu predstavljati stvarni problem s struganjem weba na strani klijenta.

Iz sigurnosnih razloga, preglednici ograničavaju HTTP zahtjeve s više podrijetla pokrenute iz skripti. A budući da na prednjem dijelu za struganje weba koristimo Javascript na strani klijenta, mogu se pojaviti CORS pogreške.

Evo primjera pokušaja struganja podataka o profilu iz CodeWarsa ...

var name = "codemzy";$.get('//www.codewars.com/users/' + name, function(response) { console.log(response);});

U vrijeme pisanja članka, pokretanje gornjeg koda daje vam grešku povezanu s CORS-om.

Ako nema Access-Control-Allow-Originzaglavlja s mjesta koje stružete, možete naići na probleme.

Loša vijest je da trebate pokrenuti ovakve zahtjeve na strani poslužitelja da biste zaobišli ovaj problem.

Whaaaaaaaat, ovo bi trebalo biti struganje weba na strani klijenta ?!

Dobra vijest je da, zahvaljujući mnogim drugim divnim programerima koji su naišli na iste probleme, ne morate sami dodirivati ​​pozadinu.

Čvrsto ostajući u okviru naše skripte za prednji kraj, možemo koristiti alate za više domena kao što su Bilo koje podrijetlo, Bilo koje podrijetlo, Sva podrijetla, crossorigin i vjerojatno puno više. Otkrio sam da često trebate testirati nekoliko od njih kako biste pronašli onu koja će raditi na web mjestu koje pokušavate sastrugati.

Povratak na naš primjer CodeWars-a, možemo poslati zahtjev putem alata za više domena kako bismo zaobišli problem CORS-a.

var name = "codemzy";var url = "//anyorigin.com/go?url=" + encodeURIComponent("//www.codewars.com/users/") + name + "&callback=?";$.get(url, function(response) { console.log(response);});

I baš poput magije, mi imamo svoj odgovor.