Ocolind limita de căutare a LinkedIn jucând cu API-ul

Limită

Există o astfel de limitare pe LinkedIn - Limită de utilizare comercială. Este extrem de probabil ca și tu, ca și mine până de curând, să nu fi întâlnit sau auzit niciodată de el.

Ocolind limita de căutare a LinkedIn jucând cu API-ul

Esența limitei este că, dacă folosești prea des căutarea persoanelor din afara contactelor tale (nu există valori exacte, algoritmul decide în funcție de acțiunile tale - cât de des și cât de mult ai căutat, ai adăugat persoane), atunci rezultatul căutării va fi limitat la trei profiluri, în loc de 1000 (implicit 100 de pagini, 10 profiluri pe pagină). Limita se resetează la începutul fiecărei luni. Natural, conturile premium nu au această limitare.

Dar nu cu mult timp în urmă, pentru un proiect pentru animale de companie, am început să mă joc mult cu căutarea pe LinkedIn și am primit brusc această limitare. Desigur, asta nu mi-a plăcut foarte mult, pentru că nu l-am folosit în scopuri comerciale, așa că primul meu gând a fost să studiez limitarea și să încerc să o ocol.

[O precizare importantă: materialele din articol sunt prezentate exclusiv în scop informativ și educațional. Autorul nu încurajează utilizarea lor în scopuri comerciale.]

Studiem problema

Avem: în loc de zece profiluri cu paginare, căutarea returnează doar trei, după care se inserează un bloc cu o „recomandare” a unui cont premium iar mai jos sunt profile neclare și neclickabile.

Imediat, mâna se întinde spre consola dezvoltatorului pentru a se uita la aceste profiluri ascunse - poate putem elimina unele stiluri de estompare sau putem extrage informații dintr-un bloc din marcaj. Dar, destul de așteptat, aceste profiluri sunt corecte imagini cu substituent și nicio informație nu este stocată.

Ocolind limita de căutare a LinkedIn jucând cu API-ul

Bine, acum să ne uităm la fila Rețea și să verificăm dacă rezultatele căutării alternative care returnează doar trei profiluri funcționează efectiv. Găsim solicitarea care ne interesează pentru „/api/search/blended” și ne uităm la răspuns.

Ocolind limita de căutare a LinkedIn jucând cu API-ul

Profilurile vin într-o matrice `included`, dar există deja 15 entități în acesta. În acest caz, primele trei dintre ele sunt obiecte cu informații suplimentare, fiecare obiect conține informații despre un anumit profil (de exemplu, dacă profilul este premium. ).

Ocolind limita de căutare a LinkedIn jucând cu API-ul

Următoarele 12 sunt profiluri reale - rezultate ale căutării, dintre care doar trei ni se vor afișa. După cum puteți ghici deja, îi arată doar pe cei care primesc informații suplimentare (primele trei obiecte). De exemplu, dacă iei răspunsul dintr-un profil fără limită, vei primi 28 de entități - 10 obiecte cu suplimentare. informatii si 18 profiluri.

Răspuns pentru profil fără limităOcolind limita de căutare a LinkedIn jucând cu API-ul
Ocolind limita de căutare a LinkedIn jucând cu API-ul

De ce sosesc mai mult de 10 profiluri, deși sunt solicitate exact 10 și nu participă în niciun fel la afișare, nici măcar pe pagina următoare nu vor fi - nu știu încă. Dacă analizați adresa URL a solicitării, puteți vedea că numărul=10 (câte profiluri să returnați în răspuns, maxim 49).

Ocolind limita de căutare a LinkedIn jucând cu API-ul

Aș fi bucuros să primesc orice comentarii pe această temă.

Să experimentăm

Bine, cel mai important lucru pe care îl știm acum cu siguranță este că există mai multe profiluri în răspuns decât ne arată. Aceasta înseamnă că putem obține mai multe date, în ciuda limitei. Să încercăm să extragem singuri API-ul, direct din consolă, folosind fetch.

Ocolind limita de căutare a LinkedIn jucând cu API-ul

După cum era de așteptat, primim o eroare, 403. Acest lucru se datorează securității, aici nu trimitem un token CSRF (CSRF pe Wikipedia. Pe scurt, la fiecare cerere este adăugat un token unic, care este verificat pe server pentru autenticitate).

Ocolind limita de căutare a LinkedIn jucând cu API-ul

Poate fi copiat din orice altă solicitare reușită sau din cookie-uri, unde este stocat în câmpul „JSESSIONID”.

Unde să găsiți jetonulAntetul altei cereri:

Ocolind limita de căutare a LinkedIn jucând cu API-ul

Sau din cookie-uri, direct prin consolă:

Ocolind limita de căutare a LinkedIn jucând cu API-ul

Să încercăm din nou, de data aceasta trecem setările pentru a prelua, în care specificăm csrf-token-ul nostru ca parametru în antet.

Ocolind limita de căutare a LinkedIn jucând cu API-ul

Succes, primim toate cele 10 profiluri. :tada:

Datorită diferenței de antete, structura răspunsului este ușor diferită de ceea ce este primit în cererea inițială. Puteți obține aceeași structură dacă adăugați „Accept: „application/vnd.linkedin.normalized+json+2.1” la obiectul nostru, lângă simbolul csrf.
Exemplu de răspuns cu antet adăugatOcolind limita de căutare a LinkedIn jucând cu API-ul

Mai multe despre antetul Accept

Ce urmeaza?

Apoi se poate edita (manual sau automat) parametrul `start`, arătând spre index, începând de la care ni se vor da 10 profiluri (implicit = 0) din întregul rezultat al căutării. Cu alte cuvinte, prin creșterea lui cu 10 după fiecare solicitare, obținem rezultatul obișnuit pagină cu pagină, câte 10 profiluri la un moment dat.

În această etapă aveam suficiente date și libertate pentru a continua să lucrez la proiectul pentru animale de companie. Dar ar fi fost un păcat să nu încerci să afișezi aceste date chiar la fața locului, deoarece erau deja la îndemână. Nu vom intra în Ember, care este folosit în față. jQuery a fost conectat la site și, după ce ați scos cunoștințele despre sintaxa de bază în memorie, puteți crea următoarele în câteva minute.

cod jQuery

/* рендер блока, принимаем данные профиля и вставляем блок в список профилей используя эти данные */
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="/ro/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="/ro/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>`
    );
};

// дергаем апи, получаем данные и рендерим профили
const fetchProfiles = () => {
    // токен
   const csrf = 'ajax:9082932176494192209';
    
   // объект с настройками запроса, передаем токен
   const settings = { headers: { 'csrf-token': csrf } }

    // урл запроса, с динамическим индексом старта в конце
   const url = `https://www.linkedin.com/voyager/api/search/blended?count=10&filters=List(geoRegion-%3Ejp%3A0,network-%3ES,resultType-%3EPEOPLE)&origin=FACETED_SEARCH&q=all&queryContext=List(spellCorrectionEnabled-%3Etrue,relatedSearchesEnabled-%3Etrue)&start=${nextItemIndex}`; 
    /* делаем запрос, для каждого профиля в ответе вызываем рендер блока, и после инкрементируем стартовый индекс на 10 */
    fetch(url, settings).then(response => response.json()).then(data => {
        data.elements[0].elements.forEach(createProfileBlock);
        nextItemIndex += 10;
});
};


// удаляем все профили из списка
$('.search-results__list').find('li').remove();
// вставляем кнопку загрузки профилей
$('.search-results__list').after('<button id="load-more">Load More</button>');
// добавляем функционал на кнопку
$('#load-more').addClass('artdeco-button').on('click', fetchProfiles);

// ставим по умолчания индекс профиля для запроса
window.nextItemIndex = 0;

Dacă faceți acest lucru direct în consola de pe pagina de căutare, va adăuga un buton care încarcă 10 profiluri noi la fiecare clic și le va reda într-o listă. Desigur, înainte de a face acest lucru, schimbați tokenul și URL-ul cu cel necesar. Blocul de profil va conține numele, poziția, locația, linkul către profil și o imagine de substituent.

Ocolind limita de căutare a LinkedIn jucând cu API-ul

Concluzie

Astfel, cu un minim de efort, am reușit să găsim punctul slab și să ne recâștigăm căutarea fără restricții. A fost suficient să analizăm datele și calea lor, să analizăm cererea în sine.

Nu pot spune că aceasta este o problemă serioasă pentru LinkedIn, deoarece nu reprezintă nicio amenințare. Maximul este profitul pierdut din cauza unor astfel de „soluții de soluționare”, care vă permite să evitați plata primei. Poate că un astfel de răspuns al serverului este necesar pentru funcționarea corectă a altor părți ale site-ului sau este pur și simplu lenea dezvoltatorilor și o lipsă de resurse care nu permite să se facă bine. (Restricția a apărut în ianuarie 2015; înainte de aceasta nu exista limită).

PS

Desigur, codul jQuery este un exemplu destul de primitiv al capabilităților. Momentan am creat o extensie de browser care să se potrivească nevoilor mele. Adaugă butoane de control și redă profiluri complete cu imagini, un buton de invitație și conexiuni generale. În plus, colectează în mod dinamic filtre pentru locații, companii și alte lucruri și preia un simbol din cookie-uri. Deci nu mai este nevoie să codificați nimic. Ei bine, adaugă câmpuri de setări suplimentare, cum ar fi „câte profiluri să solicitați simultan, până la 49”.

Ocolind limita de căutare a LinkedIn jucând cu API-ul

Încă lucrez la această adăugare și intenționez să o lansez publicului. Scrie daca esti interesat.

Sursa: www.habr.com

Adauga un comentariu