Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Limit

Na LinkedIn istnieje takie ograniczenie - Limit wykorzystania komercyjnego. Jest bardzo prawdopodobne, że tak jak ja do niedawna nigdy się z tym nie spotkałeś ani o nim nie słyszałeś.

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Istota ograniczenia polega na tym, że jeśli zbyt często korzystasz z wyszukiwania osób spoza Twoich kontaktów (nie ma dokładnych wskaźników, algorytm decyduje na podstawie Twoich działań – jak często i ile szukałeś, dodałeś osoby), to wynik wyszukiwania będzie ograniczona do trzech profili zamiast 1000 (domyślnie 100 stron, 10 profili na stronę). Limit resetowany jest na początku każdego miesiąca. Naturalnie, konta premium nie mają tego ograniczenia.

Ale nie tak dawno temu, w ramach projektu domowego, zacząłem dużo bawić się wyszukiwarką LinkedIn i nagle dostałem to ograniczenie. Oczywiście nie bardzo mi się to podobało, ponieważ nie używałem tego do celów komercyjnych, więc moją pierwszą myślą było przestudiowanie ograniczeń i próba ich obejścia.

[Ważne wyjaśnienie: materiały zawarte w artykule mają wyłącznie charakter informacyjny i edukacyjny. Autor nie zachęca do ich wykorzystania w celach komercyjnych.]

Badamy problem

Mamy: zamiast dziesięciu profili z paginacją, wyszukiwanie zwraca tylko trzy, po czym wstawiany jest blok z „rekomendacją” konta premium, a poniżej są zamazane i nieklikalne profile.

Od razu ręka sięga do konsoli programisty, żeby przyjrzeć się tym ukrytym profilom – być może uda nam się usunąć niektóre zamazane style lub wydobyć informacje z bloku w znacznikach. Ale, całkiem oczekiwanie, te profile są po prostu zdjęcia zastępcze i żadne informacje nie są przechowywane.

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

OK, teraz spójrzmy na zakładkę Sieć i sprawdźmy, czy alternatywne wyniki wyszukiwania, które zwracają tylko trzy profile, rzeczywiście działają. Znajdujemy interesujące nas żądanie dla „/api/search/blended” i patrzymy na odpowiedź.

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Profile występują w tablicy `w zestawie`, ale jest w niej już 15 encji. W tym przypadku pierwsze trzy z nich to obiekty z dodatkowymi informacjami, każdy obiekt zawiera informację na temat konkretnego profilu (np. czy profil jest premium ).

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Kolejne 12 to profile prawdziwe – wyniki wyszukiwania, z których tylko trzy zostaną nam pokazane. Jak już się domyślacie, pokazuje tylko te osoby, które otrzymają dodatkowe informacje (pierwsze trzy obiekty). Przykładowo, jeśli pobierzesz odpowiedź z profilu bez limitu, otrzymasz 28 podmiotów - 10 obiektów z dodatkowymi. informacje i 18 profili.

Odpowiedź na profil bez ograniczeńOmijanie limitu wyszukiwania LinkedIn poprzez zabawę z API
Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Dlaczego przybywa więcej niż 10 profili, chociaż żąda się dokładnie 10 i nie biorą one w żaden sposób udziału w wyświetlaniu, nawet na następnej stronie ich nie będzie - jeszcze nie wiem. Jeśli przeanalizujesz adres URL żądania, zobaczysz, że liczba wynosi 10 (ile profili zwrócić w odpowiedzi, maksymalnie 49).

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Chętnie zapoznam się z wszelkimi komentarzami w tej kwestii.

Eksperymentowanie

OK, najważniejszą rzeczą, którą teraz wiemy na pewno, jest to, że w odpowiedzi jest więcej profili, niż nam to pokazuje. Oznacza to, że możemy uzyskać więcej danych, pomimo limitu. Spróbujmy sami pobrać API, bezpośrednio z konsoli, za pomocą metody fetch.

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Zgodnie z oczekiwaniami pojawia się błąd 403. Dzieje się tak ze względów bezpieczeństwa, tutaj nie wysyłamy tokena CSRF (CSRF w Wikipedii. W skrócie do każdego żądania dodawany jest unikalny token, który jest sprawdzany na serwerze pod kątem autentyczności).

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Można go skopiować z dowolnego innego udanego żądania lub z plików cookie, gdzie jest przechowywany w polu „JSESSIONID”.

Gdzie znaleźć tokenNagłówek innego żądania:

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Lub z plików cookie, bezpośrednio przez konsolę:

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Spróbujmy jeszcze raz, tym razem przekazujemy ustawienia do fetch, w którym określamy nasz token csrf jako parametr w nagłówku.

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Sukces, otrzymujemy wszystkie 10 profili. :tada:

Ze względu na różnicę w nagłówkach struktura odpowiedzi różni się nieco od tej otrzymanej w pierwotnym żądaniu. Tę samą strukturę możesz uzyskać, jeśli dodasz do naszego obiektu obok tokena csrf „Accept: „application/vnd.linkedin.normalized+json+2.1”.
Przykładowa odpowiedź z dodanym nagłówkiemOmijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Więcej informacji o nagłówku Akceptuj

Co dalej?

Następnie możemy edytować (ręcznie lub automatycznie) parametr `start`, wskazując na indeks, od którego otrzymamy 10 profili (domyślnie = 0) z całego wyniku wyszukiwania. Innymi słowy, zwiększając go o 10 po każdym żądaniu, otrzymamy zwykły wynik strona po stronie, 10 profili na raz.

Na tym etapie miałem wystarczająco dużo danych i swobody, aby kontynuować pracę nad projektem zwierzaka. Jednak grzechem byłoby nie spróbować wyświetlić tych danych od razu, skoro były już pod ręką. Nie będziemy wchodzić w Ember, który jest używany z przodu. jQuery zostało połączone z witryną i po wykopaniu wiedzy o podstawowej składni w pamięci możesz w ciągu kilku minut utworzyć następujące elementy.

kod jQuery'ego

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

Jeśli zrobisz to bezpośrednio w konsoli na stronie wyszukiwania, zostanie dodany przycisk, który przy każdym kliknięciu ładuje 10 nowych profili i wyświetla je na liście. Oczywiście zanim to zrobisz, zmień token i adres URL na wymagany. Blok profilu będzie zawierał imię i nazwisko, stanowisko, lokalizację, link do profilu i obraz zastępczy.

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

wniosek

W ten sposób przy minimalnym wysiłku udało nam się znaleźć słaby punkt i wznowić poszukiwania bez ograniczeń. Wystarczyło przeanalizować dane i ich ścieżkę, przyjrzeć się samemu żądaniu.

Nie mogę powiedzieć, że jest to poważny problem dla LinkedIn, bo nie stanowi żadnego zagrożenia. Maksymalny jest utracony zysk z powodu takich „obejść”, co pozwala uniknąć płacenia za premię. Być może taka odpowiedź serwera jest konieczna do poprawnego działania innych części serwisu, a może to po prostu lenistwo programistów i brak zasobów, które nie pozwalają, aby było to dobrze zrobione. (Ograniczenie pojawiło się w styczniu 2015 r., wcześniej nie było limitu).

PS

Naturalnie kod jQuery jest raczej prymitywnym przykładem możliwości. W tej chwili stworzyłem rozszerzenie przeglądarki dostosowane do moich potrzeb. Dodaje przyciski sterujące i renderuje pełne profile ze zdjęciami, przyciskiem zaproszenia i ogólnymi połączeniami. Ponadto dynamicznie zbiera filtry dla lokalizacji, firm i innych rzeczy oraz pobiera token z plików cookie. Nie ma więc już potrzeby kodowania czegokolwiek na stałe. Cóż, dodaje dodatkowe pola ustawień, na przykład „ile profili zażądać jednocześnie, do 49”.

Omijanie limitu wyszukiwania LinkedIn poprzez zabawę z API

Wciąż pracuję nad tym dodatkiem i planuję udostępnić go publicznie. Napisz jeśli jesteś zainteresowany.

Źródło: www.habr.com

Dodaj komentarz