Piir
LinkedIn'il on selline piirang — . On väga tõenäoline, et teie, nagu mina hiljuti, ei ole kunagi sellega kokku puutunud ega kuulnud sellest.

Piiri olemus on selline, et kui otsite inimesi väljaspool oma kontakte liiga tihti (täpseid meetrikat ei ole, otsustab algoritm, põhinedes teie tegevusele — kui sageli ja palju te otsisite, lisasite inimesi), siis otsingu tulemus on piiratud kolme profiiliga, selle asemel et 1000 (vaikimisi 100 lehekülge, 10 profiili lehe kohta). Piir taastatakse iga kuu alguses. Loomulikult, .
Kuid mitte nii kaua aega tagasi, ühe väikese projekti jaoks, hakkasin LinkedIn'i otsingut palju katsetama ja äkki sain selle piirangu. Loomulikult ei meeldinud see mulle, kuna ma ei kasutanud seda mingil kommertseesmärgil, seega oli esimene mõte uurida piirangut ja püüda seda ületada.
[Oluline märkida — artiklis esitatud materjalid on esitatud eranditult tutvustamise ja õpikuna. Autor ei soodusta nende kasutamist kommertseesmärkidel.]
Uurime probleemi
On nii: kümne asemel, millele on leheviskamine, otsing annab ainult kolm, mille järel sisestatakse plokk 'premium konto soovitusega' ja allpool on udused ja mitteklikitud profiilid.
Käsi sirutub kohe arendaja konsooli, et vaadata neid varjatud profiile — ehk suudame eemaldada mõningaid stiile, mis panevad udustama, või tuua teavet plokist ülesehituses. Kuid, nagu oli oodata, need profiilid on vaid ja ei sisalda mingit teavet.

Hästi, nüüd vaatame Network vahelehte ja kontrollime, kas tõepoolest aktiveeritakse alternatiivne otsingutulemus, mis tagastab ainult kolm profiili. Leiame meid huvitava päringu '/api/search/blended' ja vaatame vastust.

Profiilid tulevad massiivis `included`, kuid seal on kokku 15 üksust. Antud juhul on esimesed kolm neist objektid, mis sisaldavad lisainfot, iga objekt sisaldab teavet konkreetse profiili kohta (näiteks kas profiil on premium).

Järgmised 12 on reaalsed profiilid — otsingutulemused, millest me näitame ainult kolme. Nagu võib aru saada, kuvatakse ainult neid, kellele tuleb täiendavat teavet (esimene kolm objekti). Näiteks, kui võtta vastus profiililt ilma limiidita, siis tuleb 28 üksust — 10 objekti täiendava teabega ja 18 profiili.
Vastus profiili jaoks ilma limiidita

Miks profiile tuleb rohkem kui 10, kuigi küsitakse just 10, ja need ei osale kuvamisel, isegi järgmisel lehel neid ei ole — hetkel ei tea. Kui analüüsida päringu URL-i, siis võib näha, et count=10 (kui palju profiile vastuses tagasi saata, maksimum 49).
Olen rõõmus kõikide kommentaaride üle sellel teemal.
Katsetame
Hea, kõige olulisem on, et me teame — profiile tuleb vastuses rohkem, kui meile näidatakse. See tähendab, et me saame rohkem andmeid kätte, vaatamata limiidile. Proovime ise API kõne teha, otse konsoolist, kasutades fetch.

Ootuspäraselt saame vea, 403. See on seotud turvalisusega, siin me ei saada CSRF tokenit (. Kui lühidalt öelda — igale päringule lisatakse ainulaadne token, mida serveris autentsuse kontrollimiseks kontrollitakse).

Seda saab kopeerida igast muust edukast päringust või küpsistest, kus see salvestatakse välja ‘JSESSIONID’.
Kust leida tokenTeise päringu päis:

Või küpsistest otse konsooli kaudu:

Proovime veel kord, seekord edastame fetch seadistustes, kus määrame päisesse meie csrf-token.

Edu, saame kõik 10 profiili. :tada:
Pealkirjade erinevuse tõttu on vastuse struktuur veidi erinev sellest, mis tuleb originaalses päringus. Sama struktuuri saab saada, lisades ‘Accept: ‘application/vnd.linkedin.normalized+json+2.1’, meie objekti, koos csrf tokeniga.
Näide vastusest koos lisatud päisega
Mis edasi?
Edasi saab redigeerida (käsitsi või automatiseerida) parameetrit `start`, mis näitab indeksi, millest alates antakse meile 10 profiili (vaikimisi = 0) kogu otsingu tulemuste hulgast. Teisisõnu, suurendades seda 10 võrra pärast iga päringut, saame tavalise leheküljepõhise väljundi, 10 profiili korraga.
Selles etapis oli mul piisavalt andmeid ja vabadust, et jätkata tööd oma isikliku projektiga. Kuid oleks patt proovida neid andmeid otse kohapeal visualiseerida, kui need on käes. Emberit, mida front-endis kasutatakse, me ei puuduta. Kodulehel oli ühendatud jQuery ja, meenutades põhisüntaksit, sai mõne minutiga luua järgmist.
jQuery kood
/* рендер блока, принимаем данные профиля и вставляем блок в список профилей используя эти данные */
const createProfileBlock = ({ headline, publicIdentifier, subline, title }) => {
$('.search-results__list').append(
`<li class="search-result search-result__occluded-item ember-view">
<div class="search-entity search-result search-result--person search-result--occlusion-enabled ember-view">
<div class="search-result__wrapper">
<div class="search-result__image-wrapper">
<a class="search-result__result-link ember-view" href="/et/in/${publicIdentifier}/">
<figure class="search-result__image">
<div class="ivm-image-view-model ember-view">
<img class="lazy-image ivm-view-attr__img--centered EntityPhoto-circle-4 presence-entity__image EntityPhoto-circle-4 loaded" src="http://www.userlogos.org/files/logos/give/Habrahabr3.png" />
</div>
</figure>
</a>
</div>
<div class="search-result__info pt3 pb4 ph0">
<a class="search-result__result-link ember-view" href="/et/in/${publicIdentifier}/">
<h3 class="actor-name-with-distance search-result__title single-line-truncate ember-view">
${title.text}
</h3>
</a>
<p class="subline-level-1 t-14 t-black t-normal search-result__truncate">${headline.text}</p>
<p class="subline-level-2 t-12 t-black--light t-normal search-result__truncate">${subline.text}</p>
</div>
</div>
</div>
<li>`
);
};
// hangime API'd, saame andmed ja renderdame profiilid
const fetchProfiles = () => {
// token
const csrf = 'ajax:9082932176494192209';
// objekti seaded päringu jaoks, edastame tokeni
const settings = { headers: { 'csrf-token': csrf } }
// päringu URL, dünaamilise alguse indeksiga lõpus
const url = `https://www.linkedin.com/voyager/api/search/blended?count=10&filters=List(geoRegion-jp0,network-S,resultType-PEOPLE)&origin=FACETED_SEARCH&q=all&queryContext=List(spellCorrectionEnabled-true,relatedSearchesEnabled-true)&start=${nextItemIndex}`;
/* teeme päringu, iga profiili jaoks vastuses kutsume esile ploki renderdamise ja seejärel inkrementime algindeksit 10 võrra */
fetch(url, settings).then(response => response.json()).then(data => {
data.elements[0].elements.forEach(createProfileBlock);
nextItemIndex += 10;
});
};
// eemaldame kõik profiilid nimekirjast
$('.search-results__list').find('li').remove();
// sisestame profiilide laadimise nupu
$('.search-results__list').after('<button id="load-more">Laadi rohkem</button>');
// lisame nupule funktsionaalsuse
$('#load-more').addClass('artdeco-button').on('click', fetchProfiles);
// määrame vaikimisi profiili indeksi päringuks
window.nextItemIndex = 0;
Kui seda otse otsingulehe konsoolis käivitada, lisab see nupu, mis laadib iga vajutuse korral 10 uut profiili ja esitab need nimekirjana. Loomulikult tuleb enne seda vahetada token ja url sobivaks. Profiiliblokis sisaldub nimi, amet, asukoht, link profiilile ja pildimaterjal.

Kokkuvõte
Nii suutsime minimaalsete pingutustega leida haavatava koha ja saada endale otsing ilma piiranguteta. Piisas, et analüüsida andmeid ja nende teed, uurida päringut.
Ma ei saa öelda, et see oleks LinkedInile tõsine probleem, kuna see ei kujuta endast mingit ohtu. Maksimaalne, millega arvestada, on kaotatud kasum selliste 'ümberminekute' tõttu, mis võimaldavad mitte maksta premium teenuse eest. Võimalik, et serveri vastus on vajalik teiste saidi osade korralikuks toimimiseks, või on see lihtsalt arendajate laiskus, mis tuleneb ressursside puudumisest, et asja hästi teha. (Piirang on kehtinud alates 2015. aasta jaanuarist, enne seda ei olnud mingit limiiti).
P.S.
Loomulikult on jQuery kood üsna primitiivne näide võimalustest. Praegu olen loonud oma vajaduste jaoks brauseri laienduse. See lisab kontrollnuppe ja renderdab täisväärtuslikke profiile koos piltide, kutse nuppude ja ühiste kontaktidega. Pluss see kogub dünaamiliselt asukohtade, firmade ja muu filtrid ning võtab küpsistest tokeni. Nii et midagi hardcode'ida ei ole enam vaja. Samuti lisab see täiendavaid seadevälju, nagu 'kui palju profiile korraga pärida, kuni 49'.

Ma töötan endiselt selle lisandmooduliga ning plaanin selle avalikustada. Kirjutage, kui teid huvitab.
Allikas: habr.com


