Preterpasante la serĉlimon de LinkedIn ludante kun la API

Limigi

Estas tia limigo en LinkedIn - Limo de komerca uzo. Estas ege verŝajne ke vi, kiel mi ĝis antaŭ nelonge, neniam renkontis aŭ aŭdis pri ĝi.

Preterpasante la serĉlimon de LinkedIn ludante kun la API

La esenco de la limo estas, ke se vi tro ofte uzas la serĉon de homoj ekster viaj kontaktoj (ne ekzistas precizaj metrikoj, la algoritmo decidas laŭ viaj agoj - kiom ofte kaj kiom vi serĉis, aldonis homojn), tiam la serĉrezulto. estos limigita al tri profiloj, anstataŭ 1000 (defaŭlte 100 paĝoj, 10 profiloj po paĝo). La limo estas rekomencigita komence de ĉiu monato. Nature, superkontoj ne havas ĉi tiun limigon.

Sed antaŭ nelonge, por dorlotbesta projekto, mi multe komencis ludi kun LinkedIn-serĉo kaj subite ricevis ĉi tiun limigon. Kompreneble mi ne tre ŝatis ĉi tion, ĉar mi ne uzis ĝin por komercaj celoj, do mia unua penso estis studi la limigon kaj provi ĝin ĉirkaŭi.

[Grava klarigo: la materialoj en la artikolo estas prezentitaj nur por informaj kaj edukaj celoj. La aŭtoro ne instigas ilian uzon por komercaj celoj.]

Ni studas la problemon

Ni havas: anstataŭ dek profiloj kun paĝigo, la serĉo resendas nur tri, post kiuj estas enmetita bloko kun "rekomendo" de premium-konto kaj sube estas neklaraj kaj neklakeblaj profiloj.

Tuj, la mano etendas la ellaboran konzolon por rigardi ĉi tiujn kaŝitajn profilojn - eble ni povas forigi kelkajn neklarajn stilojn aŭ ĉerpi informojn de bloko en la markado. Sed, sufiĉe atendite, ĉi tiuj profiloj estas justaj loktenilo bildoj kaj neniu informo estas konservita.

Preterpasante la serĉlimon de LinkedIn ludante kun la API

Bone, nun ni rigardu la langeton Reto kaj kontrolu ĉu la alternativaj serĉrezultoj, kiuj resendas nur tri profilojn, efektive funkcias. Ni trovas la peton pri kiu ni interesiĝas por "/api/search/blended" kaj rigardas la respondon.

Preterpasante la serĉlimon de LinkedIn ludante kun la API

Profiloj venas en tabelo `inkluzivita', sed jam estas 15 entoj en ĝi. En ĉi tiu kazo, la unuaj tri el ili estas objektoj kun pliaj informoj, ĉiu objekto enhavas informojn pri specifa profilo (ekzemple, ĉu la profilo estas premium). ).

Preterpasante la serĉlimon de LinkedIn ludante kun la API

La sekvaj 12 estas veraj profiloj - serĉrezultoj, el kiuj nur tri estos montritaj al ni. Kiel vi jam povas diveni, ĝi montras nur tiujn, kiuj ricevas pliajn informojn (la unuajn tri objektojn). Ekzemple, se vi prenas la respondon de profilo sen limo, vi ricevos 28 entojn - 10 objektojn kun pliaj. informoj kaj 18 profiloj.

Respondu por profilo sen limoPreterpasante la serĉlimon de LinkedIn ludante kun la API
Preterpasante la serĉlimon de LinkedIn ludante kun la API

Kial alvenas pli ol 10 profiloj, kvankam ĝuste 10 estas petitaj, kaj ili neniel partoprenas en la montrado, eĉ sur la sekva paĝo ili ne estos - mi ankoraŭ ne scias. Se vi analizas la petan URL, vi povas vidi tiun kalkulon=10 (kiom da profiloj redonu en la respondo, maksimume 49).

Preterpasante la serĉlimon de LinkedIn ludante kun la API

Mi volonte ricevus komentojn pri ĉi tiu afero.

Ni eksperimentu

Bone, la plej grava afero, kiun ni nun certe scias, estas, ke estas pli da profiloj en la respondo ol ili montras al ni. Ĉi tio signifas, ke ni povas akiri pli da datumoj, malgraŭ la limo. Ni provu tiri la API mem, rekte de la konzolo, uzante fetch.

Preterpasante la serĉlimon de LinkedIn ludante kun la API

Kiel atendite, ni ricevas eraron, 403. Ĉi tio estas pro sekureco, ĉi tie ni ne sendas CSRF-ĵetonon (CSRF en Vikipedio. En resumo, unika signo estas aldonita al ĉiu peto, kiu estas kontrolita sur la servilo por aŭtentikeco).

Preterpasante la serĉlimon de LinkedIn ludante kun la API

Ĝi povas esti kopiita de iu ajn alia sukcesa peto aŭ de kuketoj, kie ĝi estas konservita en la kampo 'JSESSIONID'.

Kie trovi la ĵetononKapo de alia peto:

Preterpasante la serĉlimon de LinkedIn ludante kun la API

Aŭ de kuketoj, rekte tra la konzolo:

Preterpasante la serĉlimon de LinkedIn ludante kun la API

Ni provu denove, ĉi-foje ni pasas la agordojn por preni, en kiuj ni specifu nian csrf-tokenon kiel parametron en la kaplinio.

Preterpasante la serĉlimon de LinkedIn ludante kun la API

Sukceso, ni ricevas ĉiujn 10 profilojn. :tada:

Pro la diferenco en kaplinioj, la strukturo de la respondo estas iomete malsama ol tio, kio estas ricevita en la originala peto. Vi povas akiri la saman strukturon se vi aldonas 'Accept: 'application/vnd.linkedin.normalized+json+2.1' al nia objekto, apud la csrf-ĵetono.
Ekzempla respondo kun aldonita kaplinioPreterpasante la serĉlimon de LinkedIn ludante kun la API

Pli pri la Akcepti kaplinion

Kio sekvas?

Tiam vi povas redakti (mane aŭ aŭtomate) la parametron `komenco`, indikante la indekson, ekde kiu ni ricevos 10 profilojn (defaŭlte = 0) el la tuta serĉrezulto. Alivorte, pliigante ĝin je 10 post ĉiu peto, ni ricevas la kutiman paĝ-post-paĝan eligon, 10 profilojn samtempe.

En ĉi tiu etapo mi havis sufiĉe da datumoj kaj libereco por daŭrigi labori pri la dorlotbesta projekto. Sed estus peko ne provi montri ĉi tiujn datumojn ĝuste surloke, ĉar ĝi jam estis ĉe la mano. Ni ne iros en Ember, kiu estas uzata ĉe la fronto. jQuery estis konektita al la retejo, kaj elfosinte la scion pri baza sintakso en memoro, vi povas krei la jenon en kelkaj minutoj.

jQuery-kodo

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

Se vi faras tion rekte en la konzolo sur la serĉpaĝo, ĝi aldonos butonon, kiu ŝarĝas 10 novajn profilojn per ĉiu klako kaj prezentas ilin en listo. Kompreneble, ŝanĝu la ĵetonon kaj URL al la postulata antaŭ fari tion. La profilbloko enhavos la nomon, pozicion, lokon, ligon al la profilo kaj lokokupilon bildon.

Preterpasante la serĉlimon de LinkedIn ludante kun la API

konkludo

Tiel, kun minimuma peno, ni povis trovi la malfortan punkton kaj reakiri nian serĉon sen limigoj. Sufiĉis analizi la datumojn kaj ĝian vojon, rigardi la peton mem.

Mi ne povas diri, ke ĉi tio estas grava problemo por LinkedIn, ĉar ĝi ne prezentas neniun minacon. La maksimumo estas perdita profito pro tiaj "solucioj", kio ebligas al vi eviti pagi superpagon. Eble tia servila respondo estas necesa por la ĝusta funkciado de aliaj partoj de la retejo, aŭ ĝi estas simple maldiligento de la programistoj kaj manko de rimedoj, kiuj ne permesas ĝin bone fari. (La limigo aperis en januaro 2015; antaŭ tio ne estis limo).

PS

Nature, la jQuery-kodo estas sufiĉe primitiva ekzemplo de la kapabloj. Nuntempe mi kreis retumilon por konveni miajn bezonojn. Ĝi aldonas kontrolbutonojn kaj bildigas plenajn profilojn kun bildoj, invitbutono kaj ĝeneralaj ligoj. Plie, ĝi dinamike kolektas filtrilojn por lokoj, kompanioj kaj aliaj aferoj, kaj prenas ĵetonon de kuketoj. Do ne plu necesas hardkodi ion ajn. Nu, ĝi aldonas pliajn agordajn kampojn, kiel "kiom da profiloj peti samtempe, ĝis 49."

Preterpasante la serĉlimon de LinkedIn ludante kun la API

Mi ankoraŭ laboras pri ĉi tiu aldono kaj planas liberigi ĝin al la publiko. Skribu se vi interesiĝas.

fonto: www.habr.com

Aldoni komenton