Omgå LinkedIns søkegrense ved å leke med API

Grense

Det er en slik begrensning på LinkedIn - Begrensning for kommersiell bruk. Det er ekstremt sannsynlig at du, som meg inntil nylig, aldri har møtt eller hørt om det.

Omgå LinkedIns søkegrense ved å leke med API

Essensen av grensen er at hvis du bruker søket etter personer utenfor kontaktene dine for ofte (det er ingen eksakte beregninger, algoritmen bestemmer basert på handlingene dine - hvor ofte og hvor mye du søkte, la til personer), så vil søkeresultatet vil være begrenset til tre profiler, i stedet for 1000 (standard 100 sider, 10 profiler per side). Grensen tilbakestilles i begynnelsen av hver måned. Naturlig, premium-kontoer har ikke denne begrensningen.

Men for ikke lenge siden, for et kjæledyrprosjekt, begynte jeg å leke mye med LinkedIn-søk og fikk plutselig denne begrensningen. Naturligvis likte jeg ikke dette særlig godt, fordi jeg ikke brukte det til noen kommersielle formål, så min første tanke var å studere begrensningen og prøve å omgå den.

[En viktig presisering: materialet i artikkelen presenteres utelukkende for informasjons- og pedagogiske formål. Forfatteren oppfordrer ikke til at de brukes til kommersielle formål.]

Vi studerer problemet

Vi har: i stedet for ti profiler med paginering, returnerer søket bare tre, hvoretter en blokk med en "anbefaling" av en premiumkonto settes inn og under er uskarpe og ikke-klikkbare profiler.

Umiddelbart strekker hånden seg ut til utviklerkonsollen for å se på disse skjulte profilene – kanskje vi kan fjerne noen uskarpe stiler, eller trekke ut informasjon fra en blokk i markeringen. Men ganske forventet er disse profilene rettferdige plassholderbilder og ingen informasjon lagres.

Omgå LinkedIns søkegrense ved å leke med API

Ok, la oss nå se på Network-fanen og sjekke om de alternative søkeresultatene som bare returnerer tre profiler faktisk fungerer. Vi finner forespørselen vi er interessert i for "/api/search/blended" og ser på svaret.

Omgå LinkedIns søkegrense ved å leke med API

Profiler kommer i en "inkludert" matrise, men det er allerede 15 enheter i den. I dette tilfellet er de tre første av dem objekter med tilleggsinformasjon, hvert objekt inneholder informasjon om en bestemt profil (for eksempel om profilen er premium. ).

Omgå LinkedIns søkegrense ved å leke med API

De neste 12 er ekte profiler - søkeresultater, hvorav kun tre vil bli vist til oss. Som du allerede kan gjette, viser den bare de som mottar tilleggsinformasjon (de tre første objektene). For eksempel, hvis du tar svaret fra en profil uten grense, vil du motta 28 enheter - 10 objekter med tillegg. informasjon og 18 profiler.

Svar for profil uten begrensningOmgå LinkedIns søkegrense ved å leke med API
Omgå LinkedIns søkegrense ved å leke med API

Hvorfor mer enn 10 profiler kommer, selv om nøyaktig 10 er forespurt, og de ikke deltar i visningen på noen måte, selv på neste side vil de ikke være - jeg vet ikke ennå. Hvis du analyserer forespørsels-URLen, kan du se at count=10 (hvor mange profiler som skal returneres i svaret, maksimalt 49).

Omgå LinkedIns søkegrense ved å leke med API

Jeg vil gjerne motta kommentarer om denne saken.

La oss eksperimentere

Ok, det viktigste vi nå vet med sikkerhet er at det er flere profiler i svaret enn de viser oss. Dette betyr at vi kan få mer data, til tross for grensen. La oss prøve å hente API-en selv, direkte fra konsollen, ved å bruke appetch.

Omgå LinkedIns søkegrense ved å leke med API

Som forventet får vi en feil, 403. Dette er på grunn av sikkerheten, her sender vi ikke et CSRF-token (CSRF på Wikipedia. I et nøtteskall legges et unikt token til hver forespørsel, som kontrolleres på serveren for autentisitet).

Omgå LinkedIns søkegrense ved å leke med API

Den kan kopieres fra en hvilken som helst annen vellykket forespørsel eller fra informasjonskapsler, der den er lagret i 'JSESSIONID'-feltet.

Hvor finner du tokenetOverskrift for en annen forespørsel:

Omgå LinkedIns søkegrense ved å leke med API

Eller fra informasjonskapsler, direkte gjennom konsollen:

Omgå LinkedIns søkegrense ved å leke med API

La oss prøve igjen, denne gangen sender vi innstillingene for å hente, der vi spesifiserer csrf-tokenet vårt som en parameter i overskriften.

Omgå LinkedIns søkegrense ved å leke med API

Suksess, vi mottar alle 10 profiler. :tada:

På grunn av forskjellen i overskrifter er strukturen på svaret litt forskjellig fra det som ble mottatt i den opprinnelige forespørselen. Du kan få samme struktur hvis du legger til 'Accept: 'application/vnd.linkedin.normalized+json+2.1' til objektet vårt, ved siden av csrf-tokenet.
Eksempelsvar med lagt til overskriftOmgå LinkedIns søkegrense ved å leke med API

Mer om Accept-overskriften

Hva blir det neste?

Deretter kan du redigere (manuelt eller automatisere) `start`-parameteren, peker på indeksen, fra hvilken vi vil få 10 profiler (standard = 0) fra hele søkeresultatet. Med andre ord, ved å øke den med 10 etter hver forespørsel, får vi den vanlige side-for-side-utdata, 10 profiler om gangen.

På dette stadiet hadde jeg nok data og frihet til å fortsette å jobbe med kjæledyrprosjektet. Men det ville vært synd å ikke prøve å vise disse dataene rett på stedet, siden de allerede var tilgjengelig. Vi går ikke inn på Ember, som brukes foran. jQuery var koblet til nettstedet, og etter å ha gravd ut kunnskapen om grunnleggende syntaks i minnet, kan du lage følgende på et par minutter.

jQuery-kode

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

Hvis du gjør dette direkte i konsollen på søkesiden, vil den legge til en knapp som laster inn 10 nye profiler med hvert klikk og gjengir dem i en liste. Endre selvfølgelig token og URL til den nødvendige før du gjør dette. Profilblokken vil inneholde navn, posisjon, plassering, lenke til profilen og et plassholderbilde.

Omgå LinkedIns søkegrense ved å leke med API

Konklusjon

Dermed klarte vi, med et minimum av innsats, å finne det svake stedet og gjenvinne søket uten restriksjoner. Det var nok å analysere dataene og deres vei, se på selve forespørselen.

Jeg kan ikke si at dette er et alvorlig problem for LinkedIn, fordi det ikke utgjør noen trussel. Maksimum er tapt fortjeneste på grunn av slike "løsninger", som lar deg unngå å betale for premie. Kanskje et slikt svar fra serveren er nødvendig for riktig drift av andre deler av nettstedet, eller det er rett og slett latskap hos utviklerne og mangel på ressurser som ikke lar det gjøres bra. (Begrensningen dukket opp i januar 2015; før dette var det ingen grense).

PS

Naturligvis er jQuery-koden et ganske primitivt eksempel på mulighetene. For øyeblikket har jeg laget en nettleserutvidelse som passer mine behov. Den legger til kontrollknapper og gjengir fullstendige profiler med bilder, en invitasjonsknapp og generelle forbindelser. I tillegg samler den dynamisk inn filtre for lokasjoner, selskaper og andre ting, og henter et token fra informasjonskapsler. Så det er ikke nødvendig å hardkode noe lenger. Vel, det legger til flere innstillingsfelt, a la "hvor mange profiler du skal be om om gangen, opptil 49."

Omgå LinkedIns søkegrense ved å leke med API

Jeg jobber fortsatt med dette tillegget og planlegger å gi det ut til offentligheten. Skriv hvis du er interessert.

Kilde: www.habr.com

Legg til en kommentar