LinkedInin hakurajan ohittaminen pelaamalla API:lla

Raja

LinkedInissä on tällainen rajoitus - Kaupallisen käytön raja. On erittäin todennäköistä, että sinä, kuten minä viime aikoihin asti, et ole koskaan tavannut tai kuullut siitä.

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Rajoituksen ydin on, että jos käytät liian usein kontaktiesi ulkopuolisten ihmisten hakua (tarkkoja mittareita ei ole, algoritmi päättää toimintasi perusteella - kuinka usein ja kuinka paljon hait, lisäsit ihmisiä), niin hakutulos näkyy rajoitetaan kolmeen profiiliin 1000 sijasta (oletus 100 sivua, 10 profiilia sivulla). Raja nollataan jokaisen kuukauden alussa. Luonnollisesti, Premium-tileillä ei ole tätä rajoitusta.

Mutta vähän aikaa sitten aloin leikkiä lemmikkiprojektia varten LinkedIn-haulla ja yhtäkkiä sain tämän rajoituksen. En tietenkään pitänyt tästä kovinkaan paljon, koska en käyttänyt sitä kaupallisiin tarkoituksiin, joten ensimmäinen ajatukseni oli tutkia rajoitusta ja yrittää kiertää sitä.

[Tärkeä selvennys: artikkelin materiaalit on esitetty vain tiedotus- ja koulutustarkoituksiin. Kirjoittaja ei rohkaise käyttämään niitä kaupallisiin tarkoituksiin.]

Tutkimme ongelmaa

Meillä on: kymmenen sivutusprofiilin sijasta haku palauttaa vain kolme, minkä jälkeen lisätään lohko, jossa on "suositus" premium-tilistä, ja alla on epäselviä ja ei-klikkattavia profiileja.

Välittömästi käsi kurottautuu kehittäjäkonsoliin katsomaan näitä piilotettuja profiileja – ehkä voimme poistaa joitain hämärtyneitä tyylejä tai poimia tietoja merkinnän lohkosta. Mutta odotetusti nämä profiilit ovat oikeudenmukaisia paikkamerkki kuvat eikä tietoja tallenneta.

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Okei, katsotaan nyt Verkko-välilehteä ja tarkistetaan, toimivatko vaihtoehtoiset hakutulokset, jotka palauttavat vain kolme profiilia. Löydämme kiinnostavan pyynnön "/api/search/blended" ja katsomme vastausta.

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Profiilit tulevat "sisällytettynä" taulukkoon, mutta entiteettiä on jo 15. Tässä tapauksessa niistä kolme ensimmäistä ovat objekteja, joissa on lisätietoa, jokainen objekti sisältää tietoa tietystä profiilista (esim. onko profiili premium ).

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Seuraavat 12 ovat oikeita profiileja - hakutuloksia, joista vain kolme näytetään meille. Kuten voit jo arvata, se näyttää vain ne, jotka saavat lisätietoja (kolme ensimmäistä kohdetta). Esimerkiksi, jos otat vastauksen profiilista ilman rajoituksia, saat 28 entiteettiä - 10 objektia ylimääräisinä. tiedot ja 18 profiilia.

Vastaa profiiliin ilman rajoituksiaLinkedInin hakurajan ohittaminen pelaamalla API:lla
LinkedInin hakurajan ohittaminen pelaamalla API:lla

Miksi yli 10 profiilia saapuu, vaikka täsmälleen 10 pyydetään, eivätkä ne osallistu näyttöön millään tavalla, edes seuraavalla sivulla niitä ei ole - en vielä tiedä. Jos analysoit pyynnön URL-osoitteen, näet, että count=10 (kuinka monta profiilia vastauksessa palautetaan, enintään 49).

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Otan mielelläni vastaan ​​kommentteja tähän asiaan.

Kokeillaan

Okei, tärkein asia, jonka tiedämme nyt varmasti, on, että vastauksessa on enemmän profiileja kuin ne osoittavat. Tämä tarkoittaa, että voimme saada enemmän dataa rajoituksesta huolimatta. Yritetään noutaa API itse suoraan konsolista hae-toiminnolla.

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Kuten odotettiin, saamme virheilmoituksen 403. Tämä johtuu turvallisuudesta, tässä emme lähetä CSRF-tunnusta (CSRF Wikipediassa. Lyhyesti sanottuna jokaiseen pyyntöön lisätään yksilöllinen tunnus, jonka aitous tarkistetaan palvelimella).

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Se voidaan kopioida mistä tahansa muusta onnistuneesta pyynnöstä tai evästeistä, joihin se on tallennettu JSESSIONID-kenttään.

Mistä merkki löytyyToisen pyynnön otsikko:

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Tai evästeistä suoraan konsolin kautta:

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Yritetään uudelleen, tällä kertaa välitämme haettavaksi asetukset, joissa määritämme csrf-tokenimme parametriksi otsikossa.

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Onnistui, saamme kaikki 10 profiilia. :tada:

Otsikkojen eroista johtuen vastauksen rakenne on hieman erilainen kuin alkuperäisessä pyynnössä. Saat saman rakenteen, jos lisäät objektiimme csrf-tunnuksen viereen 'Accept: 'application/vnd.linkedin.normalized+json+2.1'.
Esimerkkivastauksesta lisätty otsikkoLinkedInin hakurajan ohittaminen pelaamalla API:lla

Lisätietoja Hyväksy-otsikosta

Mitä seuraavaksi?

Sitten voit muokata (manuaalisesti tai automatisoida) `start`-parametria osoittaen indeksiin, josta alkaen saamme 10 profiilia (oletus = 0) koko hakutuloksesta. Toisin sanoen, lisäämällä sitä 10:llä jokaisen pyynnön jälkeen, saamme tavallisen sivukohtaisen tulosteen, 10 profiilia kerrallaan.

Tässä vaiheessa minulla oli tarpeeksi tietoa ja vapautta jatkaakseni lemmikkiprojektin parissa. Mutta olisi ollut synti olla yrittämättä näyttää näitä tietoja heti paikan päällä, koska se oli jo käsillä. Emme mene Emberiin, jota käytetään etupuolella. jQuery yhdistettiin sivustoon ja kun olet kaivellut muistista perussyntaksin tietämystä, voit luoda seuraavan parissa minuutissa.

jQuery koodi

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

Jos teet tämän suoraan hakusivun konsolissa, se lisää painikkeen, joka lataa 10 uutta profiilia jokaisella napsautuksella ja hahmontaa ne luettelossa. Tietenkin vaihda tunnus ja URL vaadituiksi ennen tämän tekemistä. Profiililohko sisältää nimen, aseman, sijainnin, linkin profiiliin ja paikkamerkkikuvan.

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Johtopäätös

Siten saimme vähällä vaivalla löytää heikon kohdan ja saada etsinnämme takaisin ilman rajoituksia. Se riitti analysoimaan dataa ja sen polkua, tutkimaan itse pyyntöä.

En voi sanoa, että tämä olisi vakava ongelma LinkedInille, koska se ei aiheuta uhkaa. Suurin on menetetty voitto tällaisten "kiertotapojen" vuoksi, jonka avulla voit välttää palkkion maksamisen. Ehkä tällainen palvelimen vastaus on välttämätön sivuston muiden osien oikean toiminnan kannalta, tai se on yksinkertaisesti kehittäjien laiskuutta ja resurssien puutetta, joka ei salli sitä tehdä hyvin. (Rajoitus ilmestyi tammikuussa 2015; ennen tätä rajoitusta ei ollut).

PS.

Luonnollisesti jQuery-koodi on melko primitiivinen esimerkki kyvyistä. Tällä hetkellä olen luonut tarpeisiini sopivan selainlaajennuksen. Se lisää ohjauspainikkeita ja tekee täydelliset profiilit kuvilla, kutsupainikkeella ja yleisillä yhteyksillä. Lisäksi se kerää dynaamisesti suodattimia sijainneille, yrityksille ja muille asioille ja hakee tunnuksen evästeistä. Joten ei enää tarvitse koodata mitään. No, se lisää lisäasetuskenttiä, a la "kuinka monta profiilia pyydetään kerralla, jopa 49".

LinkedInin hakurajan ohittaminen pelaamalla API:lla

Työskentelen edelleen tämän lisäyksen parissa ja aion julkaista sen yleisölle. Kirjoita jos kiinnostaa.

Lähde: will.com

Lisää kommentti