LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Ierobežot

LinkedIn ir šāds ierobežojums - Komerciālās izmantošanas ierobežojums. Ļoti iespējams, ka jūs, tāpat kā es vēl nesen, nekad neesat par to saskāries vai dzirdējis.

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Ierobežojuma būtība ir tāda, ka, ja pārāk bieži izmantojat meklēšanu personām ārpus jūsu kontaktpersonām (precīzas metrikas nav, algoritms izlemj pēc jūsu darbībām - cik bieži un cik daudz meklējāt, pievienojāt personas), tad meklēšanas rezultāts. tiks ierobežots līdz trim profiliem, nevis 1000 (noklusējuma 100 lapas, 10 profili vienā lapā). Ierobežojums tiek atiestatīts katra mēneša sākumā. Protams, premium kontiem nav šī ierobežojuma.

Bet pirms neilga laika es lolojumdzīvnieku projektam sāku daudz spēlēt ar LinkedIn meklēšanu un pēkšņi saņēmu šo ierobežojumu. Protams, man šis ļoti nepatika, jo neizmantoju to nekādiem komerciāliem nolūkiem, tāpēc mana pirmā doma bija izpētīt ierobežojumu un mēģināt apiet to.

[Svarīgs precizējums: rakstā minētie materiāli ir sniegti tikai informatīviem un izglītojošiem nolūkiem. Autors neiedrošina tos izmantot komerciālos nolūkos.]

Mēs pētām problēmu

Mums ir: desmit profilu ar lappušu vietā meklēšana atgriež tikai trīs, pēc tam tiek ievietots bloks ar premium konta “ieteikumu”, un zemāk ir izplūduši un neklikšķināmi profili.

Roka nekavējoties sniedzas pret izstrādātāja konsoli, lai apskatītu šos slēptos profilus — iespējams, mēs varam noņemt dažus aizmiglošanas stilus vai izvilkt informāciju no marķējuma bloka. Bet, diezgan sagaidāms, šie profili ir tikai vietturu attēli un informācija netiek saglabāta.

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Labi, tagad apskatīsim cilni Tīkls un pārbaudīsim, vai alternatīvie meklēšanas rezultāti, kas atgriež tikai trīs profilus, patiešām darbojas. Mēs atrodam mūs interesējošo pieprasījumu “/api/search/blended” un apskatām atbildi.

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Profili ir `iekļauta` masīvā, bet tajā jau ir 15 entītijas. Šajā gadījumā pirmie trīs no tiem ir objekti ar papildu informāciju, katrs objekts satur informāciju par konkrētu profilu (piemēram, vai profils ir premium). ).

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Nākamie 12 ir reāli profili – meklēšanas rezultāti, no kuriem mums tiks parādīti tikai trīs. Kā jau var nojaust, tas parāda tikai tos, kuri saņem papildu informāciju (pirmie trīs objekti). Piemēram, ja ņemat atbildi no profila bez ierobežojuma, jūs saņemsiet 28 entītijas - 10 objektus ar papildu. informācija un 18 profili.

Atbildēt par profilu bez ierobežojumiemLinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API
LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Kāpēc ierodas vairāk nekā 10 profili, lai gan tiek pieprasīti tieši 10, un tie nekādā veidā nepiedalās displejā, pat nākamajā lapā tie nebūs - es vēl nezinu. Ja analizējat pieprasījuma URL, varat redzēt, ka skaits = 10 (cik profilu jāatgriež atbildē, ne vairāk kā 49).

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Priecāšos saņemt jebkādus komentārus par šo jautājumu.

Eksperimentēsim

Labi, vissvarīgākā lieta, ko mēs tagad noteikti zinām, ir tas, ka atbildē ir vairāk profilu, nekā tie mums parāda. Tas nozīmē, ka mēs varam iegūt vairāk datu, neskatoties uz ierobežojumu. Mēģināsim paši izvilkt API tieši no konsoles, izmantojot funkciju Fetch.

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Kā gaidīts, tiek parādīta kļūda 403. Tas ir saistīts ar drošību, šeit mēs nenosūtām CSRF pilnvaru (CSRF Vikipēdijā. Īsumā, katram pieprasījumam tiek pievienots unikāls marķieris, kura autentiskums tiek pārbaudīts serverī).

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

To var nokopēt no jebkura cita veiksmīga pieprasījuma vai no sīkfailiem, kur tas tiek saglabāts laukā “JSESSIONID”.

Kur atrast žetonuCita pieprasījuma galvene:

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Vai no sīkfailiem tieši caur konsoli:

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Mēģināsim vēlreiz, šoreiz nododam atnesei iestatījumus, kuros galvenē kā parametru norādām mūsu csrf-tokenu.

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Veiksmi, mēs saņemam visus 10 profilus. :tada:

Galveno atšķirību dēļ atbildes struktūra nedaudz atšķiras no sākotnējā pieprasījumā saņemtās. Jūs varat iegūt tādu pašu struktūru, ja pievienojat mūsu objektam blakus csrf pilnvarai "Application/vnd.linkedin.normalized+json+2.1".
Atbildes piemērs ar pievienotu galveniLinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Vairāk par galveni Akceptēt

Ko tālāk?

Pēc tam jūs varat rediģēt (manuāli vai automatizēt) parametru `start`, norādot uz indeksu, no kura mums tiks piešķirti 10 profili (noklusējums = 0) no visa meklēšanas rezultāta. Citiem vārdiem sakot, palielinot to par 10 pēc katra pieprasījuma, mēs iegūstam parasto lapu pa lappusi, 10 profilus vienlaikus.

Šajā posmā man bija pietiekami daudz datu un brīvības, lai turpinātu darbu pie mājdzīvnieku projekta. Bet būtu bijis grēks nemēģināt šos datus parādīt tieši uz vietas, jo tie jau bija uz rokas. Mēs neiedziļināsimies Ember, kas tiek izmantots priekšpusē. jQuery tika savienots ar vietni, un, izrakuši atmiņā zināšanas par pamata sintakse, pāris minūšu laikā varat izveidot sekojošo.

jQuery kods

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

Ja to darāt tieši meklēšanas lapas konsolē, tiks pievienota poga, kas ar katru klikšķi ielādē 10 jaunus profilus un atveido tos sarakstā. Protams, pirms šīs darbības nomainiet marķieri un URL uz nepieciešamo. Profila blokā būs ietverts vārds, amats, atrašanās vieta, saite uz profilu un viettura attēls.

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Secinājums

Tādējādi ar minimālu piepūli mums izdevās atrast vājo vietu un atgūt meklējumus bez ierobežojumiem. Pietika analizēt datus un to ceļu, izpētīt pašu pieprasījumu.

Es nevaru teikt, ka LinkedIn tā ir nopietna problēma, jo tā nerada nekādus draudus. Maksimālā ir zaudētā peļņa šādu “risinājumu” dēļ, kas ļauj izvairīties no piemaksas maksāšanas. Iespējams, šāda servera atbilde ir nepieciešama citu vietnes daļu pareizai darbībai, vai arī tas ir vienkārši izstrādātāju slinkums un resursu trūkums, kas neļauj to izdarīt labi. (Ierobežojums parādījās 2015. gada janvārī; pirms tam ierobežojumu nebija).

PS

Protams, jQuery kods ir diezgan primitīvs iespēju piemērs. Šobrīd esmu izveidojis savām vajadzībām atbilstošu pārlūkprogrammas paplašinājumu. Tas pievieno vadības pogas un atveido pilnus profilus ar attēliem, ielūguma pogu un vispārīgiem savienojumiem. Turklāt tas dinamiski apkopo filtrus atrašanās vietām, uzņēmumiem un citām lietām un izgūst marķieri no sīkfailiem. Tāpēc vairs nekas nav jākodē. Nu, tas pievieno papildu iestatījumu laukus, a la “cik profilu pieprasīt vienlaikus, līdz 49”.

LinkedIn meklēšanas ierobežojumu apiešana, spēlējot ar API

Es joprojām strādāju pie šī papildinājuma un plānoju to publiskot. Rakstiet, ja interesē.

Avots: www.habr.com

Pievieno komentāru