Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Ограничение

Има такова ограничение в LinkedIn - Ограничение за търговска употреба. Изключително вероятно е и вие, както и аз доскоро, да не сте го срещали или чували за него.

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Същността на ограничението е, че ако използвате търсенето на хора извън вашите контакти твърде често (няма точни показатели, алгоритъмът решава въз основа на вашите действия - колко често и колко сте търсили, добавили хора), тогава резултатът от търсенето ще бъдат ограничени до три профила, вместо 1000 (по подразбиране 100 страници, 10 профила на страница). Лимитът се нулира в началото на всеки месец. Естествено, премиум акаунтите нямат това ограничение.

Но неотдавна, за проект за домашен любимец, започнах да играя много с търсенето в LinkedIn и изведнъж получих това ограничение. Естествено, това не ми хареса много, защото не го използвах за комерсиални цели, така че първата ми мисъл беше да проуча ограничението и да се опитам да го заобиколя.

[Важно уточнение: материалите в статията са представени само за информационни и образователни цели. Авторът не насърчава използването им за търговски цели.]

Проучваме проблема

Имаме: вместо десет профила с пагинация, търсенето връща само три, след което се вмъква блок с „препоръка“ за премиум акаунт и отдолу са размазани и некликнати профили.

Незабавно ръката се протяга към конзолата за разработчици, за да разгледа тези скрити профили - може би можем да премахнем някои стилове на замъгляване или да извлечем информация от блок в маркирането. Но, съвсем очаквано, тези профили са просто заместващи снимки и не се съхранява информация.

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Добре, сега нека да разгледаме раздела Мрежа и да проверим дали алтернативните резултати от търсенето, които връщат само три профила, наистина работят. Намираме заявката, която ни интересува за „/api/search/blended“ и гледаме отговора.

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Профилите идват във `включен` масив, но в него вече има 15 обекта.В този случай първите три от тях са обекти с допълнителна информация, всеки обект съдържа информация за конкретен профил (например дали профилът е премиум ).

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Следващите 12 са реални профили - резултати от търсене, от които ще ни бъдат показани само три. Както вече се досещате, показва само тези, които получават допълнителна информация (първите три обекта). Например, ако вземете отговора от профил без ограничение, ще получите 28 обекта - 10 обекта с допълнителни. информация и 18 профила.

Отговор за профил без ограничениеЗаобикаляне на ограничението за търсене на LinkedIn чрез игра с API
Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Защо пристигат повече от 10 профила, въпреки че се изискват точно 10 и те не участват в показването по никакъв начин, дори на следващата страница няма да бъдат - все още не знам. Ако анализирате URL адреса на заявката, можете да видите, че count=10 (колко профила да се върнат в отговора, максимум 49).

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Ще се радвам да получа коментари по този въпрос.

Нека експериментираме

Добре, най-важното нещо, което сега знаем със сигурност, е, че в отговора има повече профили, отколкото ни показват. Това означава, че можем да получим повече данни, въпреки ограничението. Нека се опитаме да изтеглим API сами, директно от конзолата, използвайки fetch.

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Както се очаква, получаваме грешка 403. Това се дължи на сигурността, тук не изпращаме CSRF токен (CSRF в Уикипедия. С две думи, към всяка заявка се добавя уникален токен, който се проверява на сървъра за автентичност).

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Може да се копира от всяка друга успешна заявка или от бисквитки, където се съхранява в полето „JSESSIONID“.

Къде да намеря токенаЗаглавие на друга заявка:

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Или от бисквитки, директно през конзолата:

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Нека опитаме отново, този път предаваме настройките за извличане, в които посочваме нашия csrf-токен като параметър в заглавката.

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Успех, получаваме всички 10 профила. :тада:

Поради разликата в заглавките, структурата на отговора е малко по-различна от получената в оригиналната заявка. Можете да получите същата структура, ако добавите „Accept: 'application/vnd.linkedin.normalized+json+2.1' към нашия обект, до csrf токена.
Примерен отговор с добавена заглавкаЗаобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Повече за заглавката Accept

Каква е следващата?

След това можете да редактирате (ръчно или автоматизирано) параметъра `start`, сочейки към индекса, започвайки от който ще ни бъдат дадени 10 профила (по подразбиране = 0) от целия резултат от търсенето. С други думи, като го увеличаваме с 10 след всяка заявка, получаваме обичайния изход страница по страница, 10 профила наведнъж.

На този етап имах достатъчно данни и свобода да продължа да работя по проекта за домашен любимец. Но би било грях да не се опитаме да покажем тези данни на място, тъй като те вече бяха на разположение. Няма да навлизаме в Ember, който се използва отпред. jQuery беше свързан със сайта и след като изкопаете знанията за основния синтаксис в паметта, можете да създадете следното за няколко минути.

jQuery код

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

Ако направите това директно в конзолата на страницата за търсене, това ще добави бутон, който зарежда 10 нови профила с всяко щракване и ги изобразява в списък. Разбира се, променете токена и URL адреса на необходимия, преди да направите това. Блокът на профила ще съдържа име, позиция, местоположение, връзка към профила и изображение на контейнер.

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Заключение

Така с минимални усилия успяхме да намерим слабото място и да възстановим търсенето без ограничения. Беше достатъчно да се анализират данните и пътя им, да се разгледа самата заявка.

Не мога да кажа, че това е сериозен проблем за LinkedIn, защото не представлява никаква заплаха. Максимумът е пропусната печалба поради такива „заобиколни решения“, което ви позволява да избегнете плащането на премия. Може би такъв отговор на сървъра е необходим за коректната работа на други части на сайта или просто мързелът на разработчиците и липсата на ресурси не позволява да се направи добре. (Ограничението се появи през януари 2015 г.; преди това нямаше ограничение).

PS

Естествено кодът на jQuery е доста примитивен пример за възможностите. В момента съм създал разширение за браузър, което да отговаря на нуждите ми. Той добавя контролни бутони и изобразява пълни профили със снимки, бутон за покана и общи връзки. Освен това той динамично събира филтри за местоположения, компании и други неща и извлича токен от бисквитки. Така че вече няма нужда да кодирате нищо. Е, той добавя допълнителни полета за настройки, а ла „колко профила да поискате наведнъж, до 49“.

Заобикаляне на ограничението за търсене на LinkedIn чрез игра с API

Все още работя върху това допълнение и планирам да го пусна на обществеността. При интерес пишете.

Източник: www.habr.com

Добавяне на нов коментар