Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Obmedziť

Na LinkedIn je takéto obmedzenie - Limit komerčného použitia. Je mimoriadne pravdepodobné, že ste sa s tým, podobne ako ja donedávna, nikdy nestretli a ani o tom nepočuli.

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Podstatou limitu je, že ak príliš často používate vyhľadávanie ľudí mimo vašich kontaktov (nie sú presné metriky, algoritmus rozhoduje na základe vašich akcií – ako často a koľko ste hľadali, pridávali ľudí), výsledok vyhľadávania bude obmedzený na tri profily namiesto 1000 (predvolených 100 stránok, 10 profilov na stránku). Limit sa obnoví na začiatku každého mesiaca. prirodzene, prémiové účty toto obmedzenie nemajú.

Ale nie je to tak dávno, čo som sa kvôli pet projektu začal veľa hrať s vyhľadávaním na LinkedIn a zrazu som dostal toto obmedzenie. Prirodzene, toto sa mi veľmi nepáčilo, pretože som to nepoužíval na žiadne komerčné účely, takže moja prvá myšlienka bola naštudovať si obmedzenie a pokúsiť sa ho obísť.

[Dôležité vysvetlenie: materiály v článku sú prezentované výlučne na informačné a vzdelávacie účely. Autor nepodporuje ich používanie na komerčné účely.]

Študujeme problém

Máme: namiesto desiatich profilov so stránkovaním vráti vyhľadávanie iba tri, za ktorými sa vloží blok s „odporúčaním“ prémiového účtu a pod ním sú rozmazané a neklikateľné profily.

Okamžite sa ruka natiahne ku konzole vývojára, aby sa pozrela na tieto skryté profily – možno môžeme odstrániť niektoré štýly rozmazania alebo extrahovať informácie z bloku v značke. Ale celkom očakávane sú tieto profily spravodlivé zástupné obrázky a neukladajú sa žiadne informácie.

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Dobre, teraz sa pozrime na kartu Sieť a skontrolujte, či alternatívne výsledky vyhľadávania, ktoré vracajú iba tri profily, skutočne fungujú. Nájdeme požiadavku, ktorá nás zaujíma pre „/api/search/blended“ a pozrieme sa na odpoveď.

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Profily sa dodávajú v poli `included`, ale je v ňom už 15 entít. V tomto prípade sú prvé tri objekty s dodatočnými informáciami, pričom každý objekt obsahuje informácie o konkrétnom profile (napríklad, či je profil prémiový). ).

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Ďalších 12 sú skutočné profily – výsledky vyhľadávania, z ktorých sa nám zobrazia len tri. Ako už tušíte, zobrazuje iba tých, ktorí dostanú dodatočné informácie (prvé tri objekty). Napríklad, ak prevezmete odpoveď z profilu bez obmedzenia, dostanete 28 subjektov - 10 objektov s ďalšími. informácie a 18 profilov.

Odpoveď pre profil bez obmedzeniaObchádzanie limitu vyhľadávania LinkedIn hraním s API
Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Prečo prichádza viac ako 10 profilov, hoci je požadovaných presne 10 a žiadnym spôsobom sa nezúčastňujú zobrazenia, dokonca ani na ďalšej stránke nebudú - zatiaľ neviem. Ak analyzujete adresu URL požiadavky, môžete vidieť, že počet = 10 (koľko profilov sa má vrátiť v odpovedi, maximálne 49).

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Bol by som rád, keby ste dostali akékoľvek pripomienky k tejto veci.

Poďme experimentovať

Dobre, najdôležitejšia vec, ktorú teraz s istotou vieme, je, že v odpovedi je viac profilov, ako nám ukazujú. To znamená, že môžeme získať viac údajov aj napriek limitu. Skúsme si API stiahnuť sami, priamo z konzoly, pomocou fetch.

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Ako sa očakávalo, dostaneme chybu 403. Je to kvôli bezpečnosti, tu neposielame token CSRF (CSRF na Wikipédii. Stručne povedané, ku každej požiadavke sa pridá jedinečný token, ktorého pravosť sa kontroluje na serveri).

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Dá sa skopírovať z akejkoľvek inej úspešnej požiadavky alebo z cookies, kde je uložený v poli 'JSESSIONID'.

Kde nájsť tokenHlavička inej žiadosti:

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Alebo zo súborov cookie priamo cez konzolu:

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Skúsme to znova, tentoraz odovzdáme nastavenia fetch, v ktorých zadáme náš csrf-token ako parameter v hlavičke.

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Úspech, dostávame všetkých 10 profilov. :tada:

Kvôli rozdielom v hlavičkách sa štruktúra odpovede mierne líši od toho, čo bolo prijaté v pôvodnej žiadosti. Rovnakú štruktúru môžete získať, ak do nášho objektu vedľa tokenu csrf pridáte 'Accept: 'application/vnd.linkedin.normalized+json+2.1'.
Príklad odpovede s pridanou hlavičkouObchádzanie limitu vyhľadávania LinkedIn hraním s API

Viac o hlavičke Prijať

Čo bude ďalej?

Potom môžete upraviť (manuálne alebo zautomatizovať) parameter `start`, ukazujúc na index, od ktorého dostaneme 10 profilov (predvolená hodnota = 0) z celého výsledku vyhľadávania. Inými slovami, zvýšením o 10 po každej požiadavke dostaneme obvyklý výstup po stránke, 10 profilov naraz.

V tejto fáze som mal dostatok údajov a slobody pokračovať v práci na projekte domáceho maznáčika. Bola by však škoda nepokúsiť sa tieto údaje zobraziť priamo na mieste, keďže už boli po ruke. Nepôjdeme do Ember, ktorý sa používa vpredu. jQuery bol pripojený k stránke a po vykopaní vedomostí o základnej syntaxi v pamäti môžete za pár minút vytvoriť nasledujúce.

kód 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="/sk/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="/sk/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;

Ak to urobíte priamo v konzole na stránke vyhľadávania, pridá sa tlačidlo, ktoré pri každom kliknutí načíta 10 nových profilov a vykreslí ich v zozname. Predtým, ako to urobíte, samozrejme zmeňte token a adresu URL na požadované. Blok profilu bude obsahovať názov, pozíciu, umiestnenie, odkaz na profil a zástupný obrázok.

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Záver

S minimálnou námahou sme tak bez obmedzení našli slabé miesto a znovu získali naše hľadanie. Stačilo analyzovať dáta a ich cestu, pozrieť sa do samotnej požiadavky.

Nemôžem povedať, že je to pre LinkedIn vážny problém, pretože nepredstavuje žiadnu hrozbu. Maximum je ušlý zisk v dôsledku takýchto „riešení“, ktoré vám umožňujú vyhnúť sa plateniu poistného. Možno je takáto odpoveď zo servera nevyhnutná pre správne fungovanie iných častí stránky, alebo je to jednoducho lenivosť vývojárov a nedostatok zdrojov, ktoré jej neumožňujú robiť dobre. (Obmedzenie sa objavilo v januári 2015, predtým nebolo žiadne obmedzenie).

PS

Prirodzene, kód jQuery je pomerne primitívnym príkladom schopností. Momentálne som vytvoril rozšírenie prehliadača, ktoré vyhovuje mojim potrebám. Pridáva ovládacie tlačidlá a vykresľuje úplné profily s obrázkami, tlačidlom pozvánky a všeobecnými prepojeniami. Navyše dynamicky zhromažďuje filtre pre miesta, spoločnosti a ďalšie veci a získava token zo súborov cookie. Takže už nie je potrebné nič tvrdo kódovať. No, pridáva ďalšie polia nastavení, a la "koľko profilov požadovať naraz, až 49."

Obchádzanie limitu vyhľadávania LinkedIn hraním s API

Na tomto prírastku stále pracujem a plánujem ho zverejniť. V prípade záujmu píšte.

Zdroj: hab.com

Pridať komentár