Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

Limit

Postoji takvo ograničenje na LinkedIn-u - Ograničenje komercijalne upotrebe. Vrlo je vjerovatno da se vi, kao i ja donedavno, nikada niste susreli niti čuli za to.

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

Suština ograničenja je u tome da ako prečesto koristite pretragu ljudi izvan svojih kontakata (nema tačnih metrika, algoritam odlučuje na osnovu vaših radnji - koliko često i koliko ste tražili, dodavali osobe), tada će rezultat pretrage će biti ograničen na tri profila, umjesto na 1000 (podrazumevano 100 stranica, 10 profila po stranici). Ograničenje se resetuje početkom svakog mjeseca. naravno, premium računi nemaju ovo ograničenje.

Ali ne tako davno, za projekat za kućne ljubimce, počeo sam mnogo da se igram sa 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 da proučim ograničenje i pokušam ga zaobići.

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

Proučavamo problem

Imamo: umjesto deset profila sa paginacijom, pretraga vraća samo tri, nakon čega se ubacuje blok sa “preporukom” premium naloga i ispod su mutni profili na koje se ne može kliknuti.

Odmah ruka dopire do konzole za programere kako bi pogledala ove skrivene profile - možda možemo ukloniti neke stilove zamućenja ili izvući informacije iz bloka u markupu. Ali, sasvim očekivano, ovi profili su pravedni slike čuvara mjesta i nikakve informacije se ne pohranjuju.

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

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

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

Profili dolaze u `included` nizu, ali u njemu se već nalazi 15 entiteta. U ovom slučaju, prva tri od njih su objekti sa dodatnim informacijama, svaki objekat sadrži informacije o određenom profilu (na primjer, da li je profil premium). ).

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

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

Odgovor za profil bez ograničenjaZaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem
Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

Zašto stiže više od 10 profila, iako se traži tačno 10, a oni ni na koji način ne učestvuju u prikazu, čak ni na sledeć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).

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

Bilo bi mi drago da dobijem bilo kakve komentare o ovom pitanju.

Hajde da eksperimentišemo

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

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

Kao što se očekivalo, dobijamo grešku, 403. Ovo je zbog sigurnosti, ovdje ne šaljemo CSRF token (CSRF na Wikipediji. Ukratko, svakom zahtjevu se dodaje jedinstveni token, koji se na serveru provjerava za autentičnost).

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se 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:

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

Ili iz kolačića, direktno preko konzole:

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

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

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

Uspjeh, primamo svih 10 profila. :tada:

Zbog razlike u zaglavljima, struktura odgovora se malo razlikuje od onoga što je primljeno u originalnom 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 zaglavljemZaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

Više o zaglavlju Accept

Što je sljedeće?

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

U ovoj fazi imao sam dovoljno podataka i slobode da nastavim raditi na projektu kućnog ljubimca. Ali bio bi grijeh ne pokušati prikazati ove podatke na licu mjesta, jer su već bili pri ruci. Nećemo ulaziti u Ember, koji se koristi na prednjoj strani. jQuery je povezan sa sajtom i nakon što ste iskopali znanje osnovne sintakse u memoriji, možete kreirati sledeće za 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="/bs/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="/bs/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 uradite direktno u konzoli na stranici za pretragu, dodaće se dugme koje učitava 10 novih profila svakim klikom i prikazuje ih na listi. Naravno, promijenite token i URL u traženi prije nego to učinite. Blok profila će sadržavati ime, poziciju, lokaciju, vezu do profila i sliku čuvara mjesta.

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

zaključak

Tako smo uz minimum truda uspjeli pronaći slabu tačku i vratiti potragu bez ograničenja. Bilo je dovoljno analizirati podatke i njihov put, pogledati sam zahtjev.

Ne mogu reći da je ovo ozbiljan problem za LinkedIn, jer ne predstavlja nikakvu prijetnju. Maksimum je izgubljena dobit zbog ovakvih "zaobilaznih rješenja", što vam omogućava da izbjegnete plaćanje premije. Možda je takav odgovor servera neophodan za ispravan rad drugih dijelova stranice, ili je to jednostavno lijenost programera i nedostatak resursa koji ne dozvoljavaju da se to dobro uradi. (Ograničenje se pojavilo u januaru 2015; prije toga nije bilo ograničenja).

PS

Naravno, jQuery kod je prilično primitivan primjer mogućnosti. Trenutno sam kreirao ekstenziju pretraživača da odgovara mojim potrebama. Dodaje kontrolna dugmad i prikazuje pune profile sa slikama, dugmetom za pozivnicu i opštim vezama. Osim toga, on dinamički prikuplja filtere za lokacije, kompanije i druge stvari i preuzima token iz kolačića. Dakle, više nema potrebe za hardkodiranjem. Pa, dodaje dodatna polja za podešavanja, a la „koliko profila zahtevati istovremeno, do 49“.

Zaobilazeći ograničenje pretraživanja LinkedIn-a igrajući se s API-jem

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

izvor: www.habr.com

Dodajte komentar