Ügyféloldali webes lekaparás JavaScript-sel a jQuery és a Regex segítségével

Amikor az első nyílt forráskódú projektemet, a codeBadges-t építettem, gondoltam, hogy könnyű lesz megszerezni a felhasználói profil adatait az összes fő kódtanuló webhelyről.

Ismertem az API hívásokat és a kérések fogadását. Úgy gondoltam, hogy a jQuery segítségével egyszerűen lehívhatom az adatokat a különféle API-kból, és felhasználhatom őket.

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

Nos, ez könnyű volt. De kiderült, hogy nem minden webhely rendelkezik nyilvános API-val, amelyből csak megragadhatja a kívánt adatokat.

De csak azért, mert nincs nyilvános API, még nem jelenti azt, hogy feladnia kell! A webes kaparás segítségével megragadhatja az adatokat, csak egy kis többletmunkával .

Nézzük meg, hogyan használhatjuk az ügyféloldali webes scrap-ot JavaScript-szel.

Például megkapom felhasználói adataimat a nyilvános freeCodeCamp profilomból. De ezeket a lépéseket bármely nyilvános HTML oldalon használhatja.

Az adatok lekaparásának első lépése a teljes oldal html-jének megragadása egy jQuery .getkérés segítségével.

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

Félelmetes, az egész oldal forráskódja éppen bejelentkezett a konzolra.

Megjegyzés: Ha ebben a szakaszban hibát észlel a No ‘Access-Control-Allow-Origin’ header is present on the requested resourcene izgulj. Görgessen le ennek a bejegyzésnek a Ne hagyja, hogy a CORS állítson meg szakaszát.

Az könnyű volt. A JavaScript és a jQuery használatával a fenti kód egy oldalt kér a www.freecodecamp.org webhelyről, akárcsak egy böngésző. És a freeCodeCamp válaszol az oldallal. Az oldal megjelenítéséhez a kódot futtató böngésző helyett a HTML kódot kapjuk meg.

És ez az, ami a webes kaparás, az adatok kinyerése a weboldalakról.

Ok, a válasz nem éppen olyan ügyes, mint az API-tól kapott adatok.

De… megvan az adat, valahol ott.

Ha megvan a forráskód, a szükséges információk benne vannak, csak meg kell ragadnunk a szükséges adatokat!

A válaszon keresztül kereshetjük a szükséges elemeket.

Tegyük fel, hogy szeretnénk tudni, hogy a felhasználó hány kihívást teljesített, abból a felhasználói profil válaszból, amelyet kaptunk.

Az írás idején a lakóautó teljesített kihívásai a felhasználói profil táblázataiba vannak rendezve. Tehát a teljes kihívások teljesítéséhez megszámolhatjuk a sorok számát.

Az egyik módszer az, hogy a teljes választ egy jQuery objektumba burkolja, így jQuery módszerekkel .find()tudjuk megszerezni az adatokat.

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

Ez jól működik - megfelelő eredményt kapunk. De ez nem jó módja annak, hogy elérjük azt az eredményt, amelyre vágyunk. Ha a választ jQuery objektummá változtatja, akkor valójában az egész oldal betöltődik, beleértve az adott oldal összes külső szkriptjét, betűtípusát és stíluslapját ... Ó, ó!

Néhány adatra van szükségünk. Tényleg nincs szükségünk az oldal betöltésére, és minden bizonnyal nem a vele járó összes külső erőforrásra.

Kiszedhetjük a szkript címkéit, majd a maradék választ futtathatjuk a jQuery-n keresztül. Ehhez a Regex segítségével megkereshetjük a szövegben a szkriptmintákat és eltávolíthatjuk őket.

Vagy még jobb, miért nem használhatja a Regex-et arra, hogy eleve megtalálja azt, amit keresünk?

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

És működik! A fenti Regex kód használatával kitesszük a táblázat fejének sorait (amelyek nem tartalmaztak kihívást), majd az összes táblázat sorával egyeztetjük a teljesített kihívások számát.

Még egyszerűbb, ha a kívánt adatok csak szöveges formában vannak a válaszban. A felhasználó írásakor a html-szerű pontok voltak

[ 1498 ]

csak arra vár, hogy kaparják.

var points = response.match(/

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

A fenti Regex mintában egyeztetjük a keresett h1 elemet, beleértve azt is, [ ]amely körülveszi a pontokat, és tetszőleges számot csoportosíthatunk a következővel: ([\d]*?).Visszatérünk egy tömbre, az első [0]elem az egész meccs, a második [1]pedig a csoportos mérkőzésünk (pontjaink ).

A Regex hasznos a karakterláncok mindenféle mintájának megfeleltetéséhez, és nagyszerű arra, hogy a válaszunkon keresztül keressük meg a szükséges adatokat.

Ugyanazt a háromlépcsős eljárást használhatja profiladatok lekaparására különböző webhelyekről:

  1. Használjon kliens oldali JavaScript-et
  2. A jQuery segítségével kaparja ki az adatokat
  3. A Regex segítségével szűrheti az adatokat a releváns információkhoz

Amíg nem találtam problémát, CORS.

Ne hagyd, hogy a CORS megállítson!

A CORS vagy a Cross-Origin erőforrásmegosztás valódi problémát jelenthet az ügyféloldali webkaparással.

Biztonsági okokból a böngészők korlátozzák a szkripteken belül kezdeményezett kereszt eredetű HTTP kéréseket. És mivel webes lekaparáshoz ügyféloldali Javascript-et használunk a kezelőfelületen, CORS-hibák léphetnek fel.

Íme egy példa, amely megpróbálja lekaparni a profiladatokat a CodeWars-ból ...

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

Az írás idején a fenti kód futtatása CORS-hibát okoz.

Ha nincs Access-Control-Allow-Originfejléc arról a helyről, amelyet kapar, akkor problémákba ütközhet.

A rossz hír az, hogy ilyen típusú kéréseket kell futtatnia szerver oldalon, hogy kikerülje ezt a problémát.

Whaaaaaaaat, ez állítólag kliens oldali web-kaparás ?!

A jó hír az, hogy sok más csodálatos fejlesztőnek köszönhetően, akik ugyanazokkal a problémákkal szembesültek, nem kell magának hozzáérnie a háttérhez.

Szigorúan maradva az elülső szkriptünkben, használhatunk domainek közötti eszközöket, például Any Origin, Whatever Origin, All Origins, crossorigin és valószínűleg még sok minden mást. Megállapítottam, hogy ezek közül gyakran ki kell próbálni néhányat, hogy megtalálja azt, amelyik működik azon a webhelyen, amelyet megpróbál kaparni.

Visszatérve a CodeWars példánkra, domainek közötti eszközön keresztül elküldhetjük kérésünket a CORS probléma megkerülésére.

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

És csakúgy, mint a varázslat, megvan a válaszunk.