Limit
Ka një kufi në LinkedIn — . Është jashtëzakonisht e mundshme që ju, ashtu si edhe unë deri përpara një kohe, nuk keni hasur dhe as nuk keni dëgjuar për të.

Thelbi i këti kufiri është se nëse përdorni kërkimin e njerëzve jashtë kontakteve tuaja shumë shpesh (nuk ka metrika të sakta, e vendos algoritmi, në bazë të veprimeve tuaja — sa shpesh dhe shumë keni kërkuar, shtuar njerëz), atëherë rezultati i kërkimit do të jetë i kufizuar në tre profile, në vend të 1000 (për default 100 faqe, me 10 profile për faqe). Limiti rikthehet në fillim të çdo muaji. Natyrisht, .
Por jo shumë kohë më parë, për një projekt të vogël, fillova të luaj shumë me kërkimin në LinkedIn dhe papritur e mora këtë kufi. Natyrisht, këtë nuk e kisha shumë për zemër, sepse nuk e përdora për ndonjë qëllim komercial, kështu që mendimi i parë ishte të studioja kufirin dhe të përpiqesha ta anashkaloj atë.
[Klarifikim i rëndësishëm — materialet në këtë artikull janë paraqitur ekskluzivisht për qëllime informuese dhe edukative. Autori nuk e inkurajon përdorimin e tyre për qëllime komerciale.]
Hulumtojmë problémën
Kemi: në vend të dhjetë profileve me paginim, kërkimi jep vetëm tri, pas të cilave vendoset një bllok me “rekomandimin” e llogarive premium dhe poshtë shfaqen profile të paqartë dhe të pa klikueshme.
Menjëherë dora shkon në konsolën e zhvilluesit, për të parë këto profile të fshehura — ndoshta mund të heqim disa stile që vendosin blurin, ose të nxjerrim informacione nga blloku në markup. Por, krejt siç pritej, këto profile janë vetëm dhe nuk mbajnë asnjë informacion.

Mirë, tani le të shohim në skedën Network dhe të kontrollojmë nëse me të vërtetë aktivizohet një dalje alternative e rezultateve të kërkimit, e cila kthen vetëm tre profile. Gjejmë kërkesën që na intereson në “/api/search/blended” dhe shikojmë në përgjigje.

Profilet vijnë në një array `included`, por entitetet në të janë 15. Në këtë rast, tre të parat janë objekte me informacion shtesë, çdo objekt përmban informacion për një profil konkret (p.sh., a është profili premium).

Të dhënat e mëposhtme janë profile reale - rezultatet e kërkimit, nga të cilat do të na tregohen vetëm tre. Siç mund të kuptohet, tregon vetëm ata që marrin informacion shtesë (objektet e para tre). Për shembull, nëse marrim përgjigjen nga profili pa limit, do të vijnë 28 entitete - 10 objekte me informacion shtesë dhe 18 profile.
Përgjigja për profilin pa limit

Pse vijnë më shumë se 10 profile, megjithëse kërkohen pikërisht 10, dhe ato nuk marrin pjesë në shfaqje, madje as në faqen tjetër nuk do të jenë - ende nuk e di. Nëse analizojmë URL-në e kërkesës mund të shohim se count=10 (sa profile do të kthehen në përgjigje, maksimumi 49).
Do të isha i lumtur për çdo koment rreth kësaj.
Po eksperimentoj
Mirë, gjëja më e rëndësishme që tani e dimë saktësisht - vijnë më shumë profile në përgjigje sesa na tregohen. Kështu që mund të nxjerrim më shumë të dhëna, pavarësisht limitit. Le të provoni të thërrasim API-në vetë, direkt nga konsola, me ndihmën e fetch.

Siç pritej, marrim një gabim, 403. Kjo lidhet me sigurinë, këtu ne nuk dërgojmë tokenin CSRF (. Nëse e shprehim me fjalë të tjera - çdo kërkesë shoqërohet me një token unik, i cili kontrollohet në server për autenticitet).

Mund të kopjohet nga çdo kërkesë tjetër e suksesshme ose nga cookies, ku ruhet në fushën 'JSESSIONID'.
Ku të gjej tokeninKreu i një kërkese tjetër:

Ose nga cookies, direkt përmes konsolës:

Po provoni përsëri, këtë herë dërgojmë në fetch parametrat e cilësimeve, në të cilat e tregojmë tokenin tonë csrf-në në header.

Sukses, po marrim të gjitha 10 profile. :tada:
Për shkak të ndryshimeve në tituj, struktura e përgjigjes është paksa e ndryshme nga ajo që vjen në kërkesën origjinale. Mund të marrim një strukturë të ngjashme, nëse shtojmë 'Accept: 'application/vnd.linkedin.normalized+json+2.1', në objektin tonë, pranë tokenit csrf.
Shembulli i përgjigjes me titullin e shtuar
Çfarë ndodh më tej?
Më pas mund të redaktojmë (duke e bërë me dorë ose automatizuar) parametrin `start`, i cili tregon indeksin nga i cili do të na jepet 10 profile (në mënyrë default = 0) nga e gjithë rezultati i kërkimit. Me fjalë të tjera, duke e inkrementuar atë me 10 pas çdo kërkese, ne kemi rezultate normale paginimi, 10 profile për herë.
Në këtë fazë, kisha mjaft të dhëna dhe liri për të vazhduar punën mbi projektin tim personal. Por ishte mëkat të mos e provonim të shfaqnim këto të dhëna direkt në vend, përderisa i kishim në dorë. Në Ember, i cili përdoret në front, nuk do të hyjmë. Në sit ishte e lidhur jQuery, dhe duke u kujtuar njohuritë themelore të sintaksës, mund të krijojmë brenda disa minutash këtë.
Kodi në 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="/sq/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="/sq/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">Më shumë</button>');
// adding functionality to the button
$('#load-more').addClass('artdeco-button').on('click', fetchProfiles);
// setting the default profile index for the request
window.nextItemIndex = 0;
Nëse e ekzekutoni këtë direkt në konsolën në faqen e kërkimit, do të shtojë një buton që ngarkon 10 profile të reja me çdo klikim dhe i rendit ato në një listë. Sigurisht, duhet të ndryshoni token dhe url përkatëse. Blloku i profilit do të përmbajë emrin, pozitën, lokacionin, lidhjen në profil dhe një imazh zëvendësues.

Përfundim
Kështu, me minimale përpjekje, mundëm të gjejmë një pikë të dobët dhe të rikthenim kërkimin pa kufizime. Mjaftoi të analizohej të dhënat dhe rruga e tyre, të shikohej në vetë kërkesën.
Nuk mund të them se kjo është një problem serioz për LinkedIn, sepse nuk paraqet ndonjë kërcënim. Maksimumi është një fitim i humbur nga këto "shkëputje", që lejon të mos paguash për premium. Ndoshta, ky përgjigje i serverit është i nevojshëm për funksionimin e duhur të pjesëve të tjera të sitit, ose ndoshta është thjesht lenia e zhvilluesve, një mungesë burimesh që nuk lejon që të bëhet mirë. (Kufizimi u shfaq nga janari i vitit 2015, para se nuk kishte asnjë kufi).
P.S.
Sigurisht, kodi në jQuery është një shembull mjaft primitiv i mundësive. Tani kam krijuar një extension për shfletuesin sipas nevojave të mia. Ai shton butona kontrolli dhe rendit profile të plota me imazhe, butonin e ftesës dhe lidhjet e përbashkëta. Po ashtu, ndjek dinamikisht filtrat e lokacioneve, kompanive dhe më shumë, nxjerr token nga cookie-t. Pra, nuk nevojitet më të bëhet asgjë hardcodade. Dhe shton fusha shtesë konfigurimi, si për shembull "sa profile të kërkohen njëherësh, deri në 49".

Për këtë shtesë ende po punoj dhe kam në plan ta bëj publik. Shkruani nëse jeni të interesuar.
Burimi: habr.com


