Ignorando o limite de pesquisa do LinkedIn brincando com a API

Limite

Existe uma grande limitação no LinkedIn - Limite de uso comercial. É extremamente provável que você, como eu até recentemente, nunca tenha encontrado ou ouvido falar dele.

Ignorando o limite de pesquisa do LinkedIn brincando com a API

A essência do limite é que se você usar a busca por pessoas fora de seus contatos com muita frequência (não há métricas exatas, o algoritmo decide com base em suas ações - com que frequência e quanto você pesquisou, adicionou pessoas), então o resultado da pesquisa será limitado a três perfis, em vez de 1000 (padrão 100 páginas, 10 perfis por página). O limite é zerado no início de cada mês. Naturalmente, contas premium não têm essa limitação.

Mas não faz muito tempo, para um projeto favorito, comecei a brincar muito com a pesquisa do LinkedIn e de repente tive essa limitação. Naturalmente não gostei muito disso, pois não o utilizava para nenhum fim comercial, então meu primeiro pensamento foi estudar a limitação e tentar contorná-la.

[Um esclarecimento importante: os materiais do artigo são apresentados apenas para fins informativos e educacionais. O autor não incentiva seu uso para fins comerciais.]

Estamos estudando o problema

Temos: em vez de dez perfis com paginação, a busca retorna apenas três, após os quais é inserido um bloco com uma “recomendação” de conta premium e abaixo estão perfis borrados e não clicáveis.

Imediatamente, a mão se estende ao console do desenvolvedor para observar esses perfis ocultos - talvez possamos remover alguns estilos de desfoque ou extrair informações de um bloco na marcação. Mas, como era de se esperar, esses perfis são apenas imagens de espaço reservado e nenhuma informação é armazenada.

Ignorando o limite de pesquisa do LinkedIn brincando com a API

Ok, agora vamos dar uma olhada na aba Rede e verificar se os resultados da pesquisa alternativa que retornam apenas três perfis realmente funcionam. Encontramos a solicitação que nos interessa para “/api/search/blended” e analisamos a resposta.

Ignorando o limite de pesquisa do LinkedIn brincando com a API

Os perfis vêm em um array `incluído`, mas já contém 15 entidades. Neste caso, os três primeiros são objetos com informações adicionais, cada objeto contém informações sobre um perfil específico (por exemplo, se o perfil é premium ).

Ignorando o limite de pesquisa do LinkedIn brincando com a API

Os próximos 12 são perfis reais - resultados de pesquisa, dos quais apenas três nos serão mostrados. Como você já pode imaginar, mostra apenas quem recebe informações adicionais (os três primeiros objetos). Por exemplo, se você tirar a resposta de um perfil sem limite, receberá 28 entidades – 10 objetos com adicional. informações e 18 perfis.

Responder por perfil sem limiteIgnorando o limite de pesquisa do LinkedIn brincando com a API
Ignorando o limite de pesquisa do LinkedIn brincando com a API

Por que chegam mais de 10 perfis, embora exatamente 10 sejam solicitados, e eles não participem da exibição de forma alguma, mesmo na próxima página não estarão - ainda não sei. Se você analisar a URL da solicitação, poderá ver que count=10 (quantos perfis retornar na resposta, máximo 49).

Ignorando o limite de pesquisa do LinkedIn brincando com a API

Eu ficaria feliz em receber quaisquer comentários sobre este assunto.

Vamos experimentar

Ok, a coisa mais importante que sabemos agora com certeza é que há mais perfis na resposta do que eles nos mostram. Isso significa que podemos obter mais dados, apesar do limite. Vamos tentar extrair a API nós mesmos, diretamente do console, usando fetch.

Ignorando o limite de pesquisa do LinkedIn brincando com a API

Como esperado, obtemos um erro 403. Isso é por questão de segurança, aqui não estamos enviando um token CSRF (CSRF na Wikipédia. Resumindo, um token exclusivo é adicionado a cada solicitação, que é verificada no servidor quanto à autenticidade).

Ignorando o limite de pesquisa do LinkedIn brincando com a API

Pode ser copiado de qualquer outra solicitação bem-sucedida ou de cookies, onde é armazenado no campo 'JSESSIONID'.

Onde encontrar o tokenCabeçalho de outra solicitação:

Ignorando o limite de pesquisa do LinkedIn brincando com a API

Ou a partir de cookies, diretamente pelo console:

Ignorando o limite de pesquisa do LinkedIn brincando com a API

Vamos tentar novamente, desta vez passamos as configurações para fetch, nas quais especificamos nosso token csrf como parâmetro no cabeçalho.

Ignorando o limite de pesquisa do LinkedIn brincando com a API

Sucesso, recebemos todos os 10 perfis. :tada:

Devido à diferença nos cabeçalhos, a estrutura da resposta é um pouco diferente daquela recebida na solicitação original. Você pode obter a mesma estrutura se adicionar 'Accept: 'application/vnd.linkedin.normalized+json+2.1' ao nosso objeto, próximo ao token csrf.
Exemplo de resposta com cabeçalho adicionadoIgnorando o limite de pesquisa do LinkedIn brincando com a API

Mais sobre o cabeçalho Aceitar

Qual é o próximo?

Depois você pode editar (manualmente ou automatizar) o parâmetro `start`, apontando para o índice, a partir do qual teremos 10 perfis (padrão = 0) de todo o resultado da pesquisa. Em outras palavras, aumentando-o em 10 após cada solicitação, obtemos a saída normal página por página, 10 perfis por vez.

Nesta fase eu tinha dados e liberdade suficientes para continuar trabalhando no projeto favorito. Mas seria um pecado não tentar exibir esses dados na hora, pois eles já estavam em mãos. Não entraremos no Ember, que é usado na frente. O jQuery foi conectado ao site e, depois de adquirir o conhecimento da sintaxe básica na memória, você pode criar o seguinte em alguns minutos.

código 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="/pt/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="/pt/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;

Se você fizer isso diretamente no console da página de pesquisa, será adicionado um botão que carrega 10 novos perfis a cada clique e os renderiza em uma lista. Claro, altere o token e o URL para os necessários antes de fazer isso. O bloco de perfil conterá o nome, cargo, localização, link para o perfil e uma imagem de espaço reservado.

Ignorando o limite de pesquisa do LinkedIn brincando com a API

Conclusão

Assim, com um mínimo de esforço, conseguimos encontrar o ponto fraco e retomar a busca sem restrições. Bastou analisar os dados e seu caminho, olhar a própria solicitação.

Não posso dizer que este seja um problema sério para o LinkedIn, porque não representa nenhuma ameaça. O máximo é o lucro perdido devido a essas “soluções alternativas”, o que permite evitar o pagamento do prêmio. Talvez tal resposta do servidor seja necessária para o correto funcionamento de outras partes do site, ou seja simplesmente preguiça dos desenvolvedores e falta de recursos que não permite que seja bem feito. (A limitação surgiu em janeiro de 2015; antes não havia limite).

PS

Naturalmente, o código jQuery é um exemplo bastante primitivo dos recursos. No momento criei uma extensão de navegador para atender às minhas necessidades. Adiciona botões de controle e renderiza perfis completos com fotos, botão de convite e conexões gerais. Além disso, ele coleta filtros dinamicamente para locais, empresas e outras coisas, e recupera um token dos cookies. Portanto, não há mais necessidade de codificar nada. Bem, ele adiciona campos de configurações adicionais, como “quantos perfis solicitar por vez, até 49”.

Ignorando o limite de pesquisa do LinkedIn brincando com a API

Ainda estou trabalhando nessa adição e pretendo divulgá-la ao público. Escreva se você estiver interessado.

Fonte: habr.com

Adicionar um comentário