Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Ograničiti

Postoji takvo ograničenje na LinkedInu - Ograničenje komercijalne upotrebe. Vrlo je vjerojatno da se vi, poput mene donedavno, nikad niste susreli niti čuli za njega.

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Suština ograničenja je da ako prečesto koristite pretragu osoba izvan vaših kontakata (nema točne metrike, algoritam odlučuje na temelju vaših radnji – koliko često i koliko ste tražili, dodavali osobe), tada rezultat pretrage bit će ograničen na tri profila, umjesto na 1000 (zadano 100 stranica, 10 profila po stranici). Ograničenje se poništava početkom svakog mjeseca. Prirodno, premium računi nemaju ovo ograničenje.

Ali nedavno, za projekt ljubimca, počeo sam se puno igrati s LinkedIn pretragom i odjednom sam dobio ovo ograničenje. Naravno, ovo mi se nije previše svidjelo, jer ga nisam koristio u komercijalne svrhe, pa mi je prva pomisao bila proučiti ograničenje i pokušati ga zaobići.

[Važno pojašnjenje: materijali u članku prikazani su isključivo u informativne i obrazovne svrhe. Autor ne potiče njihovu upotrebu u komercijalne svrhe.]

Proučavamo problem

Imamo: umjesto deset profila s paginacijom, pretraga vraća samo tri, nakon čega se ubacuje blok s “preporukom” premium računa i ispod su mutni i neklikabilni profili.

Ruka odmah ide na konzolu za razvojne programere kako bi pogledala te skrivene profile - možda možemo ukloniti neke stilove koji stvaraju zamućenje ili izvući informacije iz bloka u označavanju. Ali, sasvim očekivano, ovi profili su samo slike rezerviranog mjesta i nema pohranjenih informacija.

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

U redu, sada pogledajmo karticu Mreža i provjerimo rade li alternativni rezultati pretraživanja koji vraćaju samo tri profila. Pronalazimo zahtjev koji nas zanima za “/api/search/blended” i gledamo odgovor.

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Profili dolaze u `included` nizu, ali u njemu već postoji 15 entiteta. U ovom slučaju prva tri od njih su objekti s dodatnim informacijama, svaki objekt sadrži informacije o određenom profilu (npr. je li profil premium ).

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Sljedećih 12 su pravi profili - rezultati pretraživanja, od kojih će nam se pokazati samo tri. Kao što već možete pretpostaviti, prikazuje samo one koji primaju dodatne informacije (prva tri objekta). Na primjer, ako uzmete odgovor s profila bez ograničenja, dobit ćete 28 entiteta - 10 objekata s dodatnim. informacije i 18 profila.

Odgovor za profil bez ograničenjaZaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem
Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Zašto stigne više od 10 profila, iako se traži točno 10, a oni nikako ne sudjeluju u prikazu, čak ih ni na sljedećoj stranici neće biti - još ne znam. Ako analizirate URL zahtjeva, možete vidjeti da je count=10 (koliko profila treba vratiti u odgovoru, maksimalno 49).

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Bilo bi mi drago primiti bilo kakve komentare o ovom pitanju.

Eksperimentirajmo

U redu, najvažnija stvar koju sada sigurno znamo je da u odgovoru ima više profila nego što nam ih pokazuju. To znači da možemo dobiti više podataka, unatoč ograničenju. Pokušajmo sami izvući API, izravno iz konzole, pomoću dohvaćanja.

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Kao što je i očekivano, dobivamo pogrešku, 403. To je zbog sigurnosti, ovdje ne šaljemo CSRF token (CSRF na Wikipediji. Ukratko, svakom zahtjevu dodaje se jedinstveni token, čija se autentičnost provjerava na poslužitelju).

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Može se kopirati iz bilo kojeg drugog uspješnog zahtjeva ili iz kolačića, gdje je pohranjen u polju 'JSESSIONID'.

Gdje pronaći tokenZaglavlje drugog zahtjeva:

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Ili iz kolačića, izravno putem konzole:

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Pokušajmo ponovno, ovaj put prosljeđujemo postavke za dohvaćanje, u kojima specificiramo naš csrf-token kao parametar u zaglavlju.

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Uspjeh, primamo svih 10 profila. :tada:

Zbog razlike u zaglavljima, struktura odgovora malo se razlikuje od onoga što je primljeno u izvornom zahtjevu. Možete dobiti istu strukturu ako dodate 'Accept: 'application/vnd.linkedin.normalized+json+2.1' našem objektu, pored csrf tokena.
Primjer odgovora s dodanim zaglavljemZaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Više o zaglavlju Prihvati

Što je sljedeće?

Tada možete urediti (ručno ili automatizirano) parametar `start`, pokazujući na indeks, počevši od kojeg ćemo dobiti 10 profila (zadano = 0) iz cijelog rezultata pretraživanja. Drugim riječima, povećavajući ga za 10 nakon svakog zahtjeva, dobivamo uobičajeni izlaz stranicu po stranicu, 10 profila odjednom.

U ovoj sam fazi imao dovoljno podataka i slobode za nastavak rada na projektu ljubimca. Ali bila bi šteta ne pokušati prikazati ove podatke na licu mjesta, jer su već bili pri ruci. Nećemo ulaziti u Ember, koji se koristi sprijeda. jQuery je bio povezan sa web mjestom, a nakon što ste u memoriji iskopali znanje o osnovnoj sintaksi, možete stvoriti sljedeće u nekoliko minuta.

jQuery kod

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

Ako to učinite izravno u konzoli na stranici za pretraživanje, to će dodati gumb koji svakim klikom učitava 10 novih profila i prikazuje ih na popisu. Naravno, promijenite token i URL u traženi prije nego što to učinite. Blok profila sadržavat će ime, položaj, lokaciju, poveznicu na profil i sliku rezerviranog mjesta.

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Zaključak

Tako smo uz minimalan trud uspjeli pronaći slabu točku i ponovno pokrenuti pretragu bez ograničenja. Dovoljno je bilo analizirati podatke i njihov put, pogledati u sam zahtjev.

Ne mogu reći da je to ozbiljan problem za LinkedIn, jer ne predstavlja nikakvu prijetnju. Maksimum je izgubljena dobit zbog takvih "zaobilaznih rješenja", što vam omogućuje da izbjegnete plaćanje premije. Možda je takav odgovor servera neophodan za ispravan rad ostalih dijelova stranice ili je jednostavno riječ o lijenosti programera i nedostatku resursa koji ne dopuštaju da se to dobro izvede. (Ograničenje se pojavilo u siječnju 2015.; prije toga ograničenja nije bilo).

PS

Naravno, jQuery kod je prilično primitivan primjer mogućnosti. Trenutno sam napravio proširenje preglednika koje odgovara mojim potrebama. Dodaje kontrolne gumbe i prikazuje pune profile sa slikama, gumbom za pozivnicu i općim vezama. Osim toga, dinamički prikuplja filtre za lokacije, tvrtke i druge stvari te dohvaća token iz kolačića. Dakle, više nema potrebe za hardkodiranjem bilo čega. Pa, dodaje dodatna polja postavki, a la "koliko profila zatražiti odjednom, do 49."

Zaobilaženje LinkedInova ograničenja pretraživanja igranjem s API-jem

Još uvijek radim na ovom dodatku i planiram ga objaviti javnosti. Pišite ako ste zainteresirani.

Izvor: www.habr.com

Dodajte komentar