Obcházení limitu vyhledávání LinkedIn hraním s API

Omezit

Na LinkedIn existuje takové omezení - Limit komerčního použití. Je nanejvýš pravděpodobné, že jste se s tím, stejně jako já donedávna, nikdy nesetkali ani o něm neslyšeli.

Obcházení limitu vyhledávání LinkedIn hraním s API

Podstatou limitu je, že pokud příliš často používáte vyhledávání lidí mimo vaše kontakty (neexistují přesné metriky, algoritmus rozhoduje na základě vašich akcí – jak často a jak moc jste hledali, přidávali lidi), pak výsledek vyhledávání bude omezen na tři profily místo 1000 (výchozích 100 stránek, 10 profilů na stránku). Limit je resetován na začátku každého měsíce. Přirozeně, prémiové účty toto omezení nemají.

Ale nedávno jsem si kvůli pet projektu začal hodně hrát s vyhledáváním na LinkedIn a najednou jsem dostal toto omezení. To se mi přirozeně moc nelíbilo, protože jsem to nepoužíval pro žádné komerční účely, takže moje první myšlenka byla nastudovat si omezení a zkusit to obejít.

[Důležité upřesnění: materiály v článku jsou prezentovány pouze pro informační a vzdělávací účely. Autor nepodporuje jejich použití pro komerční účely.]

Problém studujeme

Máme: místo deseti profilů se stránkováním vrátí vyhledávání pouze tři, za nimiž se vloží blok s „doporučením“ prémiového účtu a dole jsou rozmazané a neklikatelné profily.

Okamžitě se ruka natáhne k vývojářské konzoli, aby se podívala na tyto skryté profily - možná můžeme odstranit některé styly rozmazání nebo extrahovat informace z bloku v označení. Ale docela se dalo očekávat, že tyto profily jsou spravedlivé zástupné obrázky a neukládají se žádné informace.

Obcházení limitu vyhledávání LinkedIn hraním s API

Dobře, nyní se podíváme na kartu Síť a zkontrolujeme, zda alternativní výsledky vyhledávání, které vracejí pouze tři profily, skutečně fungují. Najdeme požadavek, který nás zajímá pro „/api/search/blended“ a podíváme se na odpověď.

Obcházení limitu vyhledávání LinkedIn hraním s API

Profily přicházejí v poli `included`, ale entit je v něm již 15. V tomto případě jsou první tři objekty s dalšími informacemi, každý objekt obsahuje informace o konkrétním profilu (například zda je profil prémiový ).

Obcházení limitu vyhledávání LinkedIn hraním s API

Dalších 12 jsou skutečné profily – výsledky vyhledávání, z nichž se nám zobrazí pouze tři. Jak již tušíte, zobrazuje pouze ty, kteří dostanou další informace (první tři objekty). Pokud například převezmete odpověď z profilu bez omezení, obdržíte 28 entit - 10 objektů s dalšími. informace a 18 profilů.

Odpověď pro profil bez omezeníObcházení limitu vyhledávání LinkedIn hraním s API
Obcházení limitu vyhledávání LinkedIn hraním s API

Proč přichází více než 10 profilů, ačkoliv je požadováno přesně 10, a nijak se nepodílejí na zobrazení, dokonce ani na další stránce nebudou - zatím nevím. Pokud analyzujete adresu URL požadavku, uvidíte, že počet = 10 (kolik profilů vrátit v odpovědi, maximálně 49).

Obcházení limitu vyhledávání LinkedIn hraním s API

Budu rád za jakékoli připomínky k této záležitosti.

Experimentování

Dobrá, nejdůležitější věc, kterou nyní s jistotou víme, je, že v odpovědi je více profilů, než nám ukazují. To znamená, že i přes limit můžeme získat více dat. Zkusme si API vytáhnout sami přímo z konzole pomocí fetch.

Obcházení limitu vyhledávání LinkedIn hraním s API

Podle očekávání se zobrazí chyba 403. Důvodem je zabezpečení, zde neposíláme token CSRF (CSRF na Wikipedii. Stručně řečeno, ke každému požadavku je přidán jedinečný token, jehož pravost je na serveru zkontrolována).

Obcházení limitu vyhledávání LinkedIn hraním s API

Lze jej zkopírovat z jakéhokoli jiného úspěšného požadavku nebo z cookies, kde je uložen v poli 'JSESSIONID'.

Kde najít tokenZáhlaví jiného požadavku:

Obcházení limitu vyhledávání LinkedIn hraním s API

Nebo ze souborů cookie přímo prostřednictvím konzole:

Obcházení limitu vyhledávání LinkedIn hraním s API

Zkusíme to znovu, tentokrát předáme nastavení fetch, ve kterém jako parametr v hlavičce specifikujeme náš csrf-token.

Obcházení limitu vyhledávání LinkedIn hraním s API

Úspěch, dostáváme všech 10 profilů. :tada:

Kvůli rozdílu v hlavičkách se struktura odpovědi mírně liší od toho, co bylo přijato v původní žádosti. Stejnou strukturu můžete získat, pokud do našeho objektu vedle tokenu csrf přidáte 'Accept: 'application/vnd.linkedin.normalized+json+2.1'.
Příklad odpovědi s přidanou hlavičkouObcházení limitu vyhledávání LinkedIn hraním s API

Více o hlavičce Přijmout

Co bude dál?

Poté můžete upravit (ručně nebo zautomatizovat) parametr `start` směřující na index, od kterého dostaneme 10 profilů (výchozí = 0) z celého výsledku vyhledávání. Jinými slovy, zvýšením o 10 po každém požadavku získáme obvyklý výstup po jednotlivých stránkách, 10 profilů najednou.

V této fázi jsem měl dostatek dat a svobody, abych mohl pokračovat v práci na projektu mazlíčků. Byl by ale hřích nezkusit tato data zobrazit přímo na místě, když už byla po ruce. Nepůjdeme do Ember, který se používá vepředu. jQuery byl připojen k webu a po vykopání znalostí základní syntaxe v paměti můžete za pár minut vytvořit následující.

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="/cs/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="/cs/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;

Pokud to uděláte přímo v konzole na stránce vyhledávání, přidá se tlačítko, které s každým kliknutím načte 10 nových profilů a vykreslí je v seznamu. Před tím samozřejmě změňte token a URL na požadované. Blok profilu bude obsahovat název, pozici, umístění, odkaz na profil a zástupný obrázek.

Obcházení limitu vyhledávání LinkedIn hraním s API

Závěr

S minimálním úsilím jsme tak mohli najít slabé místo a znovu získat naše hledání bez omezení. Stačilo analyzovat data a jejich cestu, podívat se na samotný požadavek.

Nemohu říci, že je to pro LinkedIn vážný problém, protože nepředstavuje žádnou hrozbu. Maximum je ušlý zisk v důsledku takových „řešení“, což vám umožní vyhnout se placení pojistného. Možná je taková odezva serveru nezbytná pro správné fungování ostatních částí webu, nebo je to prostě lenost vývojářů a nedostatek zdrojů, které neumožňují dělat to dobře. (Omezení se objevilo v lednu 2015, předtím žádné omezení nebylo).

PS

Kód jQuery je přirozeně poměrně primitivním příkladem schopností. V tuto chvíli jsem vytvořil rozšíření prohlížeče, které vyhovuje mým potřebám. Přidává ovládací tlačítka a vykresluje plné profily s obrázky, tlačítkem pozvánky a obecnými připojeními. Navíc dynamicky shromažďuje filtry pro umístění, společnosti a další věci a získává token ze souborů cookie. Takže už není potřeba nic natvrdo kódovat. No, přidává další pole nastavení, a la "kolik profilů požadovat najednou, až 49."

Obcházení limitu vyhledávání LinkedIn hraním s API

Na tomto přírůstku stále pracuji a plánuji jej zveřejnit. V případě zájmu pište.

Zdroj: www.habr.com

Přidat komentář