Melangkau had carian LinkedIn dengan bermain dengan API

Had

Terdapat had sedemikian pada LinkedIn - Had penggunaan komersial. Berkemungkinan besar anda, seperti saya sehingga baru-baru ini, tidak pernah menemui atau mendengarnya.

Melangkau had carian LinkedIn dengan bermain dengan API

Intipati had ini ialah jika anda terlalu kerap menggunakan carian untuk orang di luar kenalan anda (tiada metrik yang tepat, algoritma memutuskan berdasarkan tindakan anda - kekerapan dan kekerapan anda mencari, menambah orang), maka hasil carian akan dihadkan kepada tiga profil, bukannya 1000 ( lalai 100 halaman, 10 profil setiap halaman). Had ditetapkan semula pada awal setiap bulan. Sememangnya, akaun premium tidak mempunyai had ini.

Tetapi tidak lama dahulu, untuk projek haiwan peliharaan, saya mula bermain banyak dengan carian LinkedIn dan tiba-tiba mendapat had ini. Sememangnya, saya tidak begitu menyukai ini, kerana saya tidak menggunakannya untuk sebarang tujuan komersial, jadi pemikiran pertama saya adalah untuk mengkaji batasan dan cuba mengatasinya.

[Penjelasan penting: bahan dalam artikel dibentangkan semata-mata untuk tujuan maklumat dan pendidikan. Penulis tidak menggalakkan penggunaannya untuk tujuan komersial.]

Kami sedang mengkaji masalah itu

Kami mempunyai: bukannya sepuluh profil dengan penomboran, carian hanya mengembalikan tiga, selepas itu blok dengan "pengesyoran" akaun premium dimasukkan dan di bawah adalah profil kabur dan tidak boleh diklik.

Dengan serta-merta, tangan menghulurkan tangan ke konsol pembangun untuk melihat profil tersembunyi ini - mungkin kita boleh mengalih keluar beberapa gaya kabur atau mengekstrak maklumat daripada blok dalam penanda. Tetapi, agak dijangka, profil ini adalah adil gambar pemegang tempat dan tiada maklumat disimpan.

Melangkau had carian LinkedIn dengan bermain dengan API

Okay, sekarang mari kita lihat tab Rangkaian dan semak sama ada hasil carian alternatif yang hanya mengembalikan tiga profil benar-benar berfungsi. Kami mencari permintaan yang kami minati untuk "/api/search/blended" dan lihat jawapannya.

Melangkau had carian LinkedIn dengan bermain dengan API

Profil datang dalam tatasusunan `disertakan`, tetapi sudah terdapat 15 entiti di dalamnya. Dalam kes ini, tiga yang pertama daripadanya ialah objek dengan maklumat tambahan, setiap objek mengandungi maklumat pada profil tertentu (contohnya, sama ada profil itu premium ).

Melangkau had carian LinkedIn dengan bermain dengan API

12 seterusnya adalah profil sebenar - hasil carian, yang mana hanya tiga akan ditunjukkan kepada kami. Seperti yang anda sudah boleh meneka, ia hanya menunjukkan mereka yang menerima maklumat tambahan (tiga objek pertama). Sebagai contoh, jika anda mengambil jawapan daripada profil tanpa had, anda akan menerima 28 entiti - 10 objek dengan tambahan. maklumat dan 18 profil.

Jawab untuk profil tanpa hadMelangkau had carian LinkedIn dengan bermain dengan API
Melangkau had carian LinkedIn dengan bermain dengan API

Mengapa lebih daripada 10 profil tiba, walaupun tepat 10 diminta, dan mereka tidak mengambil bahagian dalam paparan dalam apa cara sekalipun, walaupun pada halaman seterusnya mereka tidak akan berada - Saya belum tahu lagi. Jika anda menganalisis URL permintaan, anda boleh melihat bahawa kiraan=10 (berapa banyak profil untuk dikembalikan dalam respons, maksimum 49).

Melangkau had carian LinkedIn dengan bermain dengan API

Saya berbesar hati menerima sebarang komen mengenai perkara ini.

Mari bereksperimen

Okey, perkara paling penting yang kini kami ketahui dengan pasti ialah terdapat lebih banyak profil dalam respons daripada yang ditunjukkan kepada kami. Ini bermakna kita boleh mendapatkan lebih banyak data, walaupun hadnya. Mari cuba tarik API sendiri, terus dari konsol, menggunakan fetch.

Melangkau had carian LinkedIn dengan bermain dengan API

Seperti yang dijangkakan, kami mendapat ralat, 403. Ini disebabkan oleh keselamatan, di sini kami tidak menghantar token CSRF (CSRF di Wikipedia. Secara ringkasnya, token unik ditambahkan pada setiap permintaan, yang disemak pada pelayan untuk kesahihan).

Melangkau had carian LinkedIn dengan bermain dengan API

Ia boleh disalin daripada sebarang permintaan lain yang berjaya atau daripada kuki, di mana ia disimpan dalam medan 'JSESSIONID'.

Di mana untuk mencari tokenTajuk permintaan lain:

Melangkau had carian LinkedIn dengan bermain dengan API

Atau daripada kuki, terus melalui konsol:

Melangkau had carian LinkedIn dengan bermain dengan API

Mari cuba lagi, kali ini kami lulus tetapan untuk diambil, yang mana kami menentukan csrf-token kami sebagai parameter dalam pengepala.

Melangkau had carian LinkedIn dengan bermain dengan API

Berjaya, kami menerima kesemua 10 profil. :tada:

Disebabkan perbezaan dalam pengepala, struktur respons berbeza sedikit daripada apa yang diterima dalam permintaan asal. Anda boleh mendapatkan struktur yang sama jika anda menambah 'Terima: 'application/vnd.linkedin.normalized+json+2.1' pada objek kami, di sebelah token csrf.
Contoh respons dengan pengepala tambahanMelangkau had carian LinkedIn dengan bermain dengan API

Lebih lanjut mengenai pengepala Terima

Apa seterusnya?

Kemudian anda boleh mengedit (secara manual atau mengautomasikan) parameter `mula`, menunjuk ke indeks, bermula dari mana kami akan diberikan 10 profil (lalai = 0) daripada keseluruhan hasil carian. Dalam erti kata lain, dengan menambahnya sebanyak 10 selepas setiap permintaan, kami mendapat output halaman demi halaman biasa, 10 profil pada satu masa.

Pada peringkat ini saya mempunyai data dan kebebasan yang mencukupi untuk terus bekerja pada projek haiwan peliharaan. Tetapi adalah berdosa jika tidak cuba memaparkan data ini di tempat kejadian, kerana data itu sudah tersedia. Kami tidak akan pergi ke Ember, yang digunakan di hadapan. jQuery telah disambungkan ke tapak, dan setelah menggali pengetahuan tentang sintaks asas dalam ingatan, anda boleh mencipta yang berikut dalam beberapa minit.

kod 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="/ms/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="/ms/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;

Jika anda melakukan ini secara terus dalam konsol pada halaman carian, ia akan menambah butang yang memuatkan 10 profil baharu dengan setiap klik dan menjadikannya dalam senarai. Sudah tentu, tukar token dan URL kepada yang diperlukan sebelum melakukan ini. Blok profil akan mengandungi nama, kedudukan, lokasi, pautan ke profil dan imej pemegang tempat.

Melangkau had carian LinkedIn dengan bermain dengan API

Kesimpulan

Oleh itu, dengan usaha yang minimum, kami dapat mencari titik lemah dan mendapatkan semula pencarian kami tanpa sekatan. Ia cukup untuk menganalisis data dan laluannya, melihat ke dalam permintaan itu sendiri.

Saya tidak boleh mengatakan bahawa ini adalah masalah serius untuk LinkedIn, kerana ia tidak menimbulkan sebarang ancaman. Keuntungan maksimum adalah hilang kerana "penyelesaian" sedemikian, yang membolehkan anda mengelak daripada membayar premium. Mungkin tindak balas pelayan sedemikian diperlukan untuk operasi yang betul bagi bahagian lain tapak, atau hanya kemalasan pembangun dan kekurangan sumber yang tidak membenarkannya dilakukan dengan baik. (Had itu muncul pada Januari 2015; sebelum ini tiada had).

PS

Sememangnya, kod jQuery adalah contoh keupayaan yang agak primitif. Pada masa ini saya telah mencipta sambungan penyemak imbas untuk memenuhi keperluan saya. Ia menambah butang kawalan dan menjadikan profil penuh dengan gambar, butang jemputan dan sambungan umum. Selain itu, ia secara dinamik mengumpul penapis untuk lokasi, syarikat dan perkara lain dan mendapatkan semula token daripada kuki. Jadi tidak perlu hardcode apa-apa lagi. Nah, ia menambah medan tetapan tambahan, a la "berapa banyak profil untuk diminta pada satu masa, sehingga 49."

Melangkau had carian LinkedIn dengan bermain dengan API

Saya masih mengusahakan tambahan ini dan merancang untuk mengeluarkannya kepada umum. Tulis jika anda berminat.

Sumber: www.habr.com

Tambah komen