Як я можу отримати медіа користувача з Instagram без автентифікації як користувача?


175

Я намагаюся поставити останніх носіїв інформації в Instagram на бічну панель. Я намагаюся використовувати API Instagram для отримання медіа.

http://instagram.com/developer/endpoints/users/

У документації йдеться про GET https://api.instagram.com/v1/users/<user-id>/media/recent/, але в ньому йдеться про передачу маркера доступу OAuth. Маркер доступу являє собою дозвіл діяти від імені користувача. Я не хочу, щоб користувачі входили в Instagram, щоб бачити це на бічній панелі. Їм навіть не потрібно мати обліковий запис Instagram.

Наприклад, я можу зайти на http://instagram.com/thebrainscoop, не входячи в Instagram і побачити фотографії. Я хочу це зробити через API.

В API Instagram несанкціоновані користувацькі запити передають client_idзамість an access_token. Якщо я спробую це, я отримую:

{
  "meta":{
    "error_type":"OAuthParameterException",
    "code":400,
    "error_message":"\"access_token\" URL parameter missing. This OAuth request requires an \"access_token\" URL parameter."
  }
}

Отже, чи це неможливо? Чи немає способу отримати останні (загальнодоступні) засоби масової інформації користувача, не попросивши користувача спочатку увійти до акаунта Instagram через OAuth?


З цим плагіном можливо, просто перевірте вихідний код того, як вони отримували останні публічні носії інформації користувача, не вимагаючи від користувача ввійти в його або її обліковий запис instagram. : D smashballoon.com/instagram-feed/demo Просто потрібен ідентифікатор клієнта, маркер доступу не потрібен. : D
jehzlau

Вам потрібно авторизуватися, щоб вони могли відстежувати вас і обмежувати завантаження (ставки ...), як і кожен великий API. Існує загальнодоступне для реальних користувачів та громадське для скраперів / ботів, що зазвичай не те саме, що реальні користувачі бачитимуть рекламу та безпосередньо користуються послугою.
Крістоф Руссі

1
Жоден із цих методів більше не працює. Див stackoverflow.com/questions/49852080 / ...
Moradnejad

Відповіді:


123

Це пізно, але варто, якщо це допоможе комусь, як я цього не бачив у документації Instagram.

Щоб виконати GET https://api.instagram.com/v1/users/<user-id>/media/recent/(у даний час написання), вам фактично не потрібен маркер доступу до OAuth.

Ви можете виконати https://api.instagram.com/v1/users/[USER ID]/media/recent/?client_id=[CLIENT ID]

[CLIENT ID] буде дійсним ідентифікатором клієнта, зареєстрованим у додатку через керовані клієнти (не пов’язані з будь-яким користувачем). Ви можете отримати [USER ID] від імені користувача, виконавши запит на пошук користувачів GET: https://api.instagram.com/v1/users/search?q=[USERNAME]&client_id=[CLIENT ID]


9
Я думаю, що вони, можливо, знову передумали. Я отримую таку ж відповідь на помилку, як показано в ОП
Джеймс,

35
Це дійсно лише для додатків, створених до 17 листопада 2015 року, і вони взагалі не підтримуватимуться після червня 2016 року. Після цього вам знадобиться oauth access_token. instagram.com/developer/changelog
Dax Fohl

211
Це так дурно і дратує. Чому вони змушують маркер доступу просто відображати зображення, які вже є загальнодоступними ? Я навряд чи намагаюся їх сполоснути для кожного користувача у світі, я просто хочу показати останні клієнтські установки клієнта, не витрачаючи на це години, воюючи з ним. Гах!
Метт Флетчер

8
@ Обмеження швидкості руху автобуса, приятель.
Вальф

20
@MattFletcher - це ще дурніше, потрібно пройти огляд дозволу на додаток, і не впевнений, чи це навіть можливо, оскільки цей випадок використання "показ власного каналу клієнта на його власній веб-сторінці" не є одним із випадків використання. Да, ці обмеження смокчуть.
Сімантичний

334

var name = "smena8m";
$.get("https://images"+~~(Math.random()*3333)+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=https://www.instagram.com/" + name + "/", function(html) {
if (html) {
    var regex = /_sharedData = ({.*);<\/script>/m,
        json = JSON.parse(regex.exec(html)[1]),
        edges = json.entry_data.ProfilePage[0].graphql.user.edge_owner_to_timeline_media.edges;

      $.each(edges, function(n, edge) {
          var node = edge.node;
          $('body').append(
              $('<a/>', {
              href: 'https://instagr.am/p/'+node.shortcode,
              target: '_blank'
          }).css({
              backgroundImage: 'url(' + node.thumbnail_src + ')'
          }));
      });
    }
});
html, body {
  font-size: 0;
  line-height: 0;
}

a {
  display: inline-block;
  width: 25%;
  height: 0;
  padding-bottom: 25%;
  background: #eee 50% 50% no-repeat;
  background-size: cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Ви можете завантажити будь-яку стрічку фотографій користувача Instagram у форматі JSON, використовуючи ?__a=1поруч із цією адресою цільової сторінки . Не потрібно отримувати ідентифікатор користувача або реєструвати додаток, ні лексеми, ні oAuth.

min_idі max_idзмінні можуть використовуватися для пагинації, ось приклад

YQLможе не працювати тут всередині відірваного iframe, тому ви завжди можете перевірити це вручну в консолі YQL

ОНОВЛЕННЯ КВІТНЯ 2018: Після останніх оновлень інстаграм ви не можете цього робити на стороні клієнта (javascript), оскільки власні заголовки для підписаного запиту не можуть бути встановлені через javascript через CORS Access-Control-Allow-Headersобмеження. Це ще можна зробити це з допомогою phpабо будь-якого іншого методу на стороні сервера при правильній підписи на основі rhx_gis, csrf_tokenі параметри запиту. Більше про це можна прочитати тут .

ОНОВЛЕННЯ СІЧНЯ 2019 року: YQL вийшов у відставку, тому перевірте моє останнє оновлення з Google Image Proxy як CORSпроксі для сторінки Instagram! Тоді лише негативний момент - пагинація недоступна за допомогою цього методу.

PHP рішення:

    $html = file_get_contents('https://instagram.com/apple/');
    preg_match('/_sharedData = ({.*);<\/script>/', $html, $matches);
    $profile_data = json_decode($matches[1])->entry_data->ProfilePage[0]->graphql->user;

14
@ 350D Як ти це знайшов? Я не можу його знайти ніде в їх документації. Я просто хочу прочитати більше про те, що можливо з цією кінцевою точкою (зображення квадратів EG проти неквадратичних, чи планується це закінчення в червні тощо) - Дякую!
Філ Джонстон

8
@Phil Johnston Просто дослідження 😀 Візьміть ще одне - ви можете додати / media /? Size = L поруч із URL-адресою цільової сторінки фотографії та отримати ПОВНОМУ фотографії з роздільною здатністю.
350Д

9
@ user2659694 Я нарешті знайшов рішення отримати наступні сторінки за допомогою цього методу, який ви можете використовувати / media /? max_id = [MAX_ID]
Reza

3
FYI, здається, працює лише в тому випадку, якщо ви самі ввійшли в обліковий запис Instagram. Спробуйте зробити це в режимі Incognito в Chrome або подібному, і ви побачите, що відповідь JSON не містить елементів. Я намагався включити це в сценарій, щоб отримати список URL-адрес на веб-сервері, і мені довелося повернутися до старих методів авторизації.
Ryan Zink

9
@RyanZink ви пробували приватний акаунт? він працює нормально для мене, який вийшов із системи або анонімно в публічних облікових записах.
ryan

41

11.11.2017
Оскільки Instagram змінив спосіб надання цих даних, на сьогоднішній день жоден з перерахованих вище методів не працює. Ось новий спосіб отримати медіа користувача:
GET https://instagram.com/graphql/query/?query_id=17888483320059182&variables={"id":"1951415043","first":20,"after":null}
Де:
query_id- постійне значення: 17888483320059182 (зауважте, що це може бути змінено в майбутньому).
id- ідентифікатор користувача. Він може поставитись із списком користувачів. Щоб отримати список користувачів, ви можете скористатися наступним запитом: GET https://www.instagram.com/web/search/topsearch/?context=blended&query=YOUR_QUERY
first- кількість предметів, які потрібно отримати.
after- ідентифікатор останнього елемента, якщо ви хочете отримати елементи з цього ідентифікатора.


Скажіть, будь ласка, звідки мені отримати query_id та ідентифікатор користувача?
Vijaysinh Parmar

2
Як я вже згадував, @VijaysinhParmar query_id- це постійне значення. Це означає, що це завжди 17888483320059182 (принаймні, якщо Instagram не змінить). id користувача - це ідентифікатор користувача (трохи відредагував мою відповідь)
Footniko

1
Я точно не пам’ятаю, десь в Інтернеті. Але я не маю жодних стосунків з Instagram, тому у випадку, якщо він зміниться, я не зможу сказати вам нове :(
Footniko

1
Цікаво, яка політика обмеження ставок такого підходу?
kkzxak47

1
Якщо у когось є проблеми із запитом цієї URL-адреси через CURL-запит, вам потрібно отримати заголовок запиту cookie (відкрийте вкладку "Мережі", після запуску URL-адреси скопіюйте заголовок файлу cookie та вставте його в заголовок запиту curl. Якщо ви цього не зробите, ви отримаєте помилку з відхиленням доступу 403).
Андерс

40

Мені вдалося отримати останні носії інформації користувача, використовуючи наступний API без автентифікації (включаючи опис, лайки, кількість коментарів).

https://www.instagram.com/apple/?__a=1

Напр

https://www.instagram.com/{username}/?__a=1

1
це також працювало для мене.але, коли "is_video = true", немає URL-адреси відео у даних.
didikee

4
Правильно, ви можете отримати лише ескізи (а не саме відео) - на жаль, я не знайшов жодної офіційної документації на це, і я не маю уявлення, чи цей API застарілий або як довго його підтримуватимуть.
Михайло

8
Станом на 2018-04-13, схоже, це більше не працює. Можливо, через останній скандал з інформацією про Cambridge Analytica у Facebook, вони посилюють щось на тон. Будь-які інші пропозиції щодо отримання основних даних користувачів без автентифікації?
BakerStreetSystems

2
Так, був такий час, що цей API не працював - але тепер він знову
Майкл

4
Це працювало для мене, але лише тоді, коли я ввійшов в Instagram.
зунді

16

Станом на минулого тижня в Інваліді відключені /media/URL-адреси, я реалізував рішення, яке наразі працює досить добре.

Щоб вирішити всі проблеми в цій темі, я написав це: https://github.com/whizzzkid/instagram-reverse-proxy

Він надає всі загальнодоступні дані instagram, використовуючи наступні кінцеві точки:

Отримати медіа користувача:

https://igapi.ga/<username>/media
e.g.: https://igapi.ga/whizzzkid/media 

Отримайте медіа користувачів з обмеженою кількістю:

https://igapi.ga/<username>/media?count=N // 1 < N < 20
e.g.: https://igapi.ga/whizzzkid/media?count=5

Використовуйте JSONP:

https://igapi.ga/<username>/media?callback=foo
e.g.: https://igapi.ga/whizzzkid/media?callback=bar

API проксі також додає до відповіді URL-адреси наступної сторінки та попередніх сторінок, тому вам не потрібно обчислювати це в кінці.

Сподіваюсь, вам сподобається!

Дякуємо @ 350D, що помітили це :)


1
@rex, поки вони не змінить, як все працює в їх кінці, ми хороші! Вони не турбувались протягом останніх 3 років, ймовірно, не стануть у наступні 3.
whizzzkid

3
@whizzzkid Невдача, вони це змінюють. Я бачив, що ви думаєте, що кінцева точка користувача зробить це, але для запитів користувачів, які не ввійшли в систему, є обмеження. Будь-які ідеї?
nobilik

1
@nobilik рішення вирішено, і igpi.ga/whizzzkid/media?count=3 та igpi.ga/graphql/query/?user_id=1606740656&count=3 повинні повернути вам дані. Пам'ятайте, що для цих URL-адрес вимкнено не визначені посилання.
whizzzkid

1
@whizzzkid - Зробив це! Велике спасибі - ви вчений і джентльмен!
Джеймс Трікі

1
Мені з'являється помилка "референдуму було відмовлено у доступі". Може, це вже не працює?
khalid13

14

API API вимагає аутентифікації користувача через OAuth для доступу до останніх кінцевих точок медіа для користувача. Зараз, мабуть, немає іншого способу отримати всі носії для користувача.


4
Це не має сенсу, якщо я хочу відображати свої власні засоби масової інформації на власному веб-сайті, навіщо мені потрібні всі, хто хоче бачити його, щоб мати обліковий запис в instagram?
ninjasense

5
ninjasense - я не думаю, що це так працює. Я думаю, що на вашому веб-сайті знадобиться трохи коду, який би запитував API Instagram із вашими обліковими даними oauth, наданими для залучення ваших медіа. Потім ви показуватимете свій медіа будь-яким користувачам вашого сайту. Ваш сайт був би єдиним, що потрібно пройти автентифікацію в Instagram.
Білл Роулінсон

9

Якщо ви шукаєте спосіб генерувати маркер доступу для використання в одному обліковому записі, ви можете спробувати це -> https://coderwall.com/p/cfgneq .

Мені знадобився спосіб використовувати інстаграм api, щоб схопити всі найновіші носії інформації для певного облікового запису.


5
Це більш-менш те, що я зробив врешті-решт: створив новий обліковий запис, зробив маркер доступу до нього та зберіг цей маркер у моїй конфігурації сервера поруч із ключем API. Це невдале рішення для програм JS, оскільки воно вимагає доставку маркера доступу користувачеві (що я бачив багато прикладу коду). На щастя для мене, я можу це зробити на стороні сервера.
Peeja

4
@CraigHeneveld Як ви продовжуєте оновлювати шапки access_token? У вас це не минуло?
Райан Руд

Чи лексема закінчується деякий час?
Монітус

Якщо моя пам'ять слугує мені, ключ закінчується, лише якщо ви зміните свій пароль. Ось ще одна нитка з цього питання -> stackoverflow.com/questions/22753170 / ...
Craig Heneveld

Як ми можемо отримати кілька фотографій користувача ?? Як ми можемо передати кілька ідентифікаторів користувачів, розділених на ","?
Ааділ Кешвані

9

Ось варіанти рейок. Це свого роду задні двері, які насправді є вхідними.

# create a headless browser
b = Watir::Browser.new :phantomjs
uri = 'https://www.instagram.com/explore/tags/' + query
uri = 'https://www.instagram.com/' + query if type == 'user'

b.goto uri

# all data are stored on this page-level object.
o = b.execute_script( 'return window._sharedData;')

b.close

Об'єкт, який ви отримуєте назад, залежить від того, чи це пошук користувача чи пошук тегів. Я отримую такі дані:

if type == 'user'
  data = o[ 'entry_data' ][ 'ProfilePage' ][ 0 ][ 'user' ][ 'media' ][ 'nodes' ]
  page_info = o[ 'entry_data' ][ 'ProfilePage' ][ 0 ][ 'user' ][ 'media' ][ 'page_info' ]
  max_id = page_info[ 'end_cursor' ]
  has_next_page = page_info[ 'has_next_page' ]
else
  data = o[ 'entry_data' ][ 'TagPage' ][ 0 ][ 'tag' ][ 'media' ][ 'nodes' ]
  page_info = o[ 'entry_data' ][ 'TagPage' ][ 0 ][ 'tag' ][ 'media' ][ 'page_info' ]
  max_id = page_info[ 'end_cursor' ]
  has_next_page = page_info[ 'has_next_page' ]
end

Потім я отримую іншу сторінку результатів, будуючи URL таким чином:

  uri = 'https://www.instagram.com/explore/tags/' + query_string.to_s\
    + '?&max_id=' + max_id.to_s
  uri = 'https://www.instagram.com/' + query_string.to_s + '?&max_id='\
    + max_id.to_s if type === 'user'

це рішення працює для мене, але я маю з цим певні проблеми. Після завантаження даних мій сервер рейлів (використовуючи сервер Rails 5.0.0, Puma 3.6.0) непомітно перезапускається ... Будь-яке можливе рішення?
Луїс Едуардо Рохас Кабрера

8

Завдяки постійно змінюваній (і жахливо розробленій) схемі API в Інтернеті більшість з вищезазначених більше не працюватиме з квітня 2018 року.

Ось останній шлях до доступу до окремих публікаційних даних, якщо ви запитуєте їх API безпосередньо за допомогою https://www.instagram.com/username/?__a=1методу.

Якщо припустити, що повернуті вами JSONдані, $dataви можете переглядати кожен результат, використовуючи наступні приклади шляху:

foreach ($data->graphql->user->edge_owner_to_timeline_media->edges as $item) {

    $content_id = $item->node->id; 
    $date_posted = $item-node->taken_at_timestamp;
    $comments = $item->node->edge_media_to_comment->count;
    $likes = $item->node->edge_liked_by->count;
    $image = $item->node->display_url;
    $content = $item->node->edge_media_to_caption->edges[0]->node->text;
    // etc etc ....
}

Основними у цій нещодавній зміні були graphqlі edge_owner_to_timeline_media.

Схоже, вони закриють цей доступ до API для непрофесійних клієнтів у DEC 2018, тому максимально використовуйте його, поки можете.

Сподіваюся, це комусь допоможе;)


Це просто допомогло мені, я просто хочу показати останні записи про instagram для клієнта. Дякую!
Вестон дебоер

1
instagram.com/username/?__a=1 дає помилку: доступ у веб-сайті www.instagram.com було відхилено. Ви не маєте права на перегляд цієї сторінки. HTTP ERROR 403 якісь інші ідеї?
Хесе

1
Так, Instagram зараз знищив це. "Щоб постійно вдосконалювати конфіденційність та безпеку користувачів Instagram, ми прискорюємо припинення роботи платформи API Instagram, вводячи такі зміни негайно. Ми розуміємо, що це може вплинути на ваш бізнес чи послуги, і ми цінуємо вашу підтримку в захисті нашої платформи. Ці можливості буде негайно вимкнено (раніше встановлено на 31 липня 2018 року або на 11 грудня 2018 року, знецінення). "
пряність

Якщо те, що я читаю, правильно, більше не можна буде отримати зображення чи дані з будь-якого "некомерційного" облікового запису. Вони повністю знищують API платформи. Я думаю, що це тоді ... instagram.com/developer/changelog
спеція

1
@james_tookey не зможе бути товаришем. Через нові обмеження конфіденційності він більше не зможе запитувати або отримувати користувачів / дані особистих облікових записів, лише ділові. В основному вони просто знищили все використання API для особистих облікових записів.
спеція

7

JSFiddle

Javascript:

$(document).ready(function(){

    var username = "leomessi";
    var max_num_items = 5;

    var jqxhr = $.ajax( "https://www.instagram.com/"+username+"/?__a=1" ).done(function() {
        //alert( "success" );
    }).fail(function() {
        //alert( "error" );
    }).always(function(data) {
        //alert( "complete" )
        items = data.graphql.user.edge_owner_to_timeline_media.edges;
        $.each(items, function(n, item) {
            if( (n+1) <= max_num_items )
            {
                var data_li = "<li><a target='_blank' href='https://www.instagram.com/p/"+item.node.shortcode+"'><img src='" + item.node.thumbnail_src + "'/></a></li>";
                $("ul.instagram").append(data_li);
            }
        });

    });

});

HTML:

<ul class="instagram">
</ul>

CSS:

ul.instagram {
    list-style: none;
}

ul.instagram li {
  float: left;
}

ul.instagram li img {
    height: 100px;
}

5

Просто хочу додати у відповідь @ 350D, оскільки мені було важко зрозуміти.

Моя логіка в коді наступна:

Коли я дзвоню API вперше, я дзвоню лише https://www.instagram.com/_vull_ /media/. Коли я отримую відповідь, я перевіряю булеве значення more_available. Якщо це правда, я дістаю останнє фото з масиву, дістаю його ідентифікатор і знову зателефоную API Instagram, але цього разу https://www.instagram.com/_vull_/media/?max_id=1400286183132701451_1642962433.

Тут важливо знати, що цей Id - це Id останнього зображення в масиві. Тож запитуючи maxId з останнім ідентифікатором зображення в масиві, ви отримаєте наступні 20 зображень тощо.

Сподіваюся, що це прояснить речі.


4

Якщо ви обходите Oauth, ви, мабуть, не знаєте, хто це користувач instagram. При цьому, існує кілька способів отримати зображення в instagram без автентифікації.

  1. API API дозволяє переглядати найпопулярніші зображення користувача без автентифікації. Використання наступної кінцевої точки: Ось посилання

  2. Instagram надає RSS - канали для тегів в цьому .

  3. Сторінки користувача Instagram є загальнодоступними, тому ви можете використовувати PHP за допомогою CURL, щоб отримати їх сторінку та аналізатор DOM для пошуку в HTML за потрібними тегами зображень.


9
Здається застарілим.
Бурак Токак

чи можна обійти аутентифікацію для
instagram

3

Ще одна хитрість - пошук фотографій за допомогою хештегів:

GET https://www.instagram.com/graphql/query/?query_hash=3e7706b09c6184d5eafd8b032dbcf487&variables={"tag_name":"nature","first":25,"after":""}

Де:

query_hash - постійне значення (я вірю, його хеш 17888483320059182, можна змінити в майбутньому)

tag_name - назва говорить сама за себе

first - кількість предметів, які потрібно отримати (я не знаю чому, але це значення працює не так, як очікувалося. Фактична кількість повернених фотографій трохи більша за значення, помножене на 4,5 (приблизно 110 для значення 25 і приблизно 460 для значення 100))

after- ідентифікатор останнього елемента, якщо ви хочете отримати елементи з цього ідентифікатора. Значення end_cursorвід відповіді JSON можна використати тут.


Як ви це знаходите?
ekntrtmz


3

Якщо ви хочете шукати користувачів, не маючи clientID та маркер доступу:

1: Якщо ви хочете шукати всіх користувачів, які мають ваші імена, схожі на ваше пошукове слово:

замініть SeachName текстом, який ви хочете шукати:

https://www.instagram.com/web/search/topsearch/?query=SearchName

2: якщо ви хочете шукати саме того імені користувача:

замініть UserName на бажане ім'я пошуку:

https://www.instagram.com/UserName/?__a=1


2

Ви можете використовувати цей API для отримання загальнодоступної інформації користувача instagram:
https://api.lityapp.com/instagrams/thebrainscoop?limit=2

Якщо не встановити граничний параметр, публікації за замовчуванням обмежені на 12.

Це api було зроблено у SpringBoot з HtmlUnit, як ви бачите у коді:

public JSONObject getPublicInstagramByUserName(String userName, Integer limit) {
    String html;
    WebClient webClient = new WebClient();

    try {
        webClient.getOptions().setCssEnabled(false);
        webClient.getOptions().setJavaScriptEnabled(false);
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        webClient.getCookieManager().setCookiesEnabled(true);

        Page page = webClient.getPage("https://www.instagram.com/" + userName);
        WebResponse response = page.getWebResponse();

        html = response.getContentAsString();
    } catch (Exception ex) {
        ex.printStackTrace();

        throw new RuntimeException("Ocorreu um erro no Instagram");
    }

    String prefix = "static/bundles/es6/ProfilePageContainer.js";
    String sufix = "\"";
    String script = html.substring(html.indexOf(prefix));

    script = script.substring(0, script.indexOf(sufix));

    try {
        Page page = webClient.getPage("https://www.instagram.com/" + script);
        WebResponse response = page.getWebResponse();

        script = response.getContentAsString();
    } catch (Exception ex) {
        ex.printStackTrace();

        throw new RuntimeException("Ocorreu um erro no Instagram");
    }

    prefix = "l.pagination},queryId:\"";

    String queryHash = script.substring(script.indexOf(prefix) + prefix.length());

    queryHash = queryHash.substring(0, queryHash.indexOf(sufix));
    prefix = "<script type=\"text/javascript\">window._sharedData = ";
    sufix = ";</script>";
    html = html.substring(html.indexOf(prefix) + prefix.length());
    html = html.substring(0, html.indexOf(sufix));

    JSONObject json = new JSONObject(html);
    JSONObject entryData = json.getJSONObject("entry_data");
    JSONObject profilePage = (JSONObject) entryData.getJSONArray("ProfilePage").get(0);
    JSONObject graphql = profilePage.getJSONObject("graphql");
    JSONObject user = graphql.getJSONObject("user");
    JSONObject response = new JSONObject();

    response.put("id", user.getString("id"));
    response.put("username", user.getString("username"));
    response.put("fullName", user.getString("full_name"));
    response.put("followedBy", user.getJSONObject("edge_followed_by").getLong("count"));
    response.put("following", user.getJSONObject("edge_follow").getLong("count"));
    response.put("isBusinessAccount", user.getBoolean("is_business_account"));
    response.put("photoUrl", user.getString("profile_pic_url"));
    response.put("photoUrlHD", user.getString("profile_pic_url_hd"));

    JSONObject edgeOwnerToTimelineMedia = user.getJSONObject("edge_owner_to_timeline_media");
    JSONArray posts = new JSONArray();

    try {
        loadPublicInstagramPosts(webClient, queryHash, user.getString("id"), posts, edgeOwnerToTimelineMedia, limit == null ? 12 : limit);
    } catch (Exception ex) {
        ex.printStackTrace();

        throw new RuntimeException("Você fez muitas chamadas, tente mais tarde");
    }

    response.put("posts", posts);

    return response;
}

private void loadPublicInstagramPosts(WebClient webClient, String queryHash, String userId, JSONArray posts, JSONObject edgeOwnerToTimelineMedia, Integer limit) throws IOException {
    JSONArray edges = edgeOwnerToTimelineMedia.getJSONArray("edges");

    for (Object elem : edges) {
        if (limit != null && posts.length() == limit) {
            return;
        }

        JSONObject node = ((JSONObject) elem).getJSONObject("node");

        if (node.getBoolean("is_video")) {
            continue;
        }

        JSONObject post = new JSONObject();

        post.put("id", node.getString("id"));
        post.put("shortcode", node.getString("shortcode"));

        JSONArray captionEdges = node.getJSONObject("edge_media_to_caption").getJSONArray("edges");

        if (captionEdges.length() > 0) {
            JSONObject captionNode = ((JSONObject) captionEdges.get(0)).getJSONObject("node");

            post.put("caption", captionNode.getString("text"));
        } else {
            post.put("caption", (Object) null);
        }

        post.put("photoUrl", node.getString("display_url"));

        JSONObject dimensions = node.getJSONObject("dimensions");

        post.put("photoWidth", dimensions.getLong("width"));
        post.put("photoHeight", dimensions.getLong("height"));

        JSONArray thumbnailResources = node.getJSONArray("thumbnail_resources");
        JSONArray thumbnails = new JSONArray();

        for (Object elem2 : thumbnailResources) {
            JSONObject obj = (JSONObject) elem2;
            JSONObject thumbnail = new JSONObject();

            thumbnail.put("photoUrl", obj.getString("src"));
            thumbnail.put("photoWidth", obj.getLong("config_width"));
            thumbnail.put("photoHeight", obj.getLong("config_height"));
            thumbnails.put(thumbnail);
        }

        post.put("thumbnails", thumbnails);
        posts.put(post);
    }

    JSONObject pageInfo = edgeOwnerToTimelineMedia.getJSONObject("page_info");

    if (!pageInfo.getBoolean("has_next_page")) {
        return;
    }

    String endCursor = pageInfo.getString("end_cursor");
    String variables = "{\"id\":\"" + userId + "\",\"first\":12,\"after\":\"" + endCursor + "\"}";

    String url = "https://www.instagram.com/graphql/query/?query_hash=" + queryHash + "&variables=" + URLEncoder.encode(variables, "UTF-8");
    Page page = webClient.getPage(url);
    WebResponse response = page.getWebResponse();
    String content = response.getContentAsString();
    JSONObject json = new JSONObject(content);

    loadPublicInstagramPosts(webClient, queryHash, userId, posts, json.getJSONObject("data").getJSONObject("user").getJSONObject("edge_owner_to_timeline_media"), limit);
}


Це приклад відповіді:

{
  "id": "290482318",
  "username": "thebrainscoop",
  "fullName": "Official Fan Page",
  "followedBy": 1023,
  "following": 6,
  "isBusinessAccount": false,
  "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/447ffd0262082f373acf3d467435f130/5C709C77/t51.2885-19/11351770_612904665516559_678168252_a.jpg",
  "photoUrlHD": "https://scontent-gru2-1.cdninstagram.com/vp/447ffd0262082f373acf3d467435f130/5C709C77/t51.2885-19/11351770_612904665516559_678168252_a.jpg",
  "posts": [
    {
      "id": "1430331382090378714",
      "shortcode": "BPZjtBUly3a",
      "caption": "If I have any active followers anymore; hello! I'm Brianna, and I created this account when I was just 12 years old to show my love for The Brain Scoop. I'm now nearly finished high school, and just rediscovered it. I just wanted to see if anyone is still active on here, and also correct some of my past mistakes - being a child at the time, I didn't realise I had to credit artists for their work, so I'm going to try to correct that post haste. Also; the font in my bio is horrendous. Why'd I think that was a good idea? Anyway, this is a beautiful artwork of the long-tailed pangolin by @chelsealinaeve . Check her out!",
      "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/ab823331376ca46136457f4654bf2880/5CAD48E4/t51.2885-15/e35/16110915_400942200241213_3503127351280009216_n.jpg",
      "photoWidth": 640,
      "photoHeight": 457,
      "thumbnails": [
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/43b195566d0ef2ad5f4663ff76d62d23/5C76D756/t51.2885-15/e35/c91.0.457.457/s150x150/16110915_400942200241213_3503127351280009216_n.jpg",
          "photoWidth": 150,
          "photoHeight": 150
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/ae39043a7ac050c56d741d8b4355c185/5C93971C/t51.2885-15/e35/c91.0.457.457/s240x240/16110915_400942200241213_3503127351280009216_n.jpg",
          "photoWidth": 240,
          "photoHeight": 240
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/ae7a22d09e3ef98d0a6bbf31d621a3b7/5CACBBA6/t51.2885-15/e35/c91.0.457.457/s320x320/16110915_400942200241213_3503127351280009216_n.jpg",
          "photoWidth": 320,
          "photoHeight": 320
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/1439dc72b70e7c0c0a3afcc30970bb13/5C8E2923/t51.2885-15/e35/c91.0.457.457/16110915_400942200241213_3503127351280009216_n.jpg",
          "photoWidth": 480,
          "photoHeight": 480
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/1439dc72b70e7c0c0a3afcc30970bb13/5C8E2923/t51.2885-15/e35/c91.0.457.457/16110915_400942200241213_3503127351280009216_n.jpg",
          "photoWidth": 640,
          "photoHeight": 640
        }
      ]
    },
    {
      "id": "442527661838057235",
      "shortcode": "YkLJBXJD8T",
      "caption": null,
      "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/dc94b38da679826b9ac94ccd2bcc4928/5C7CDF93/t51.2885-15/e15/11327349_860747310663863_2105199307_n.jpg",
      "photoWidth": 612,
      "photoHeight": 612,
      "thumbnails": [
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/c1153c6513c44a6463d897e14b2d8f06/5CB13ADD/t51.2885-15/e15/s150x150/11327349_860747310663863_2105199307_n.jpg",
          "photoWidth": 150,
          "photoHeight": 150
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/47e60ec8bca5a1382cd9ac562439d48c/5CAE6A82/t51.2885-15/e15/s240x240/11327349_860747310663863_2105199307_n.jpg",
          "photoWidth": 240,
          "photoHeight": 240
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/da0ee5b666ab40e4adc1119e2edca014/5CADCB59/t51.2885-15/e15/s320x320/11327349_860747310663863_2105199307_n.jpg",
          "photoWidth": 320,
          "photoHeight": 320
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/02ee23571322ea8d0992e81e72f80ef2/5C741048/t51.2885-15/e15/s480x480/11327349_860747310663863_2105199307_n.jpg",
          "photoWidth": 480,
          "photoHeight": 480
        },
        {
          "photoUrl": "https://scontent-gru2-1.cdninstagram.com/vp/dc94b38da679826b9ac94ccd2bcc4928/5C7CDF93/t51.2885-15/e15/11327349_860747310663863_2105199307_n.jpg",
          "photoWidth": 640,
          "photoHeight": 640
        }
      ]
    }
  ]
}

чи можу я отримати дані користувачем userid (pk)
SAURABH RATHOD

Вибачте @SAURABHRATHOD Я спробував, але не знайшов способу це зробити. Я був би дуже радий, якщо хтось вирішить це. Дякуємо за коментар
Руан

2

Мені дуже потрібна ця функція, але для Wordpress. Я підходив і це працювало чудово

<script>
    jQuery(function($){
        var name = "caririceara.comcariri";
        $.get("https://images"+~~(Math.random()*33)+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=https://www.instagram.com/" + name + "/", function(html) {
            if (html) {
                var regex = /_sharedData = ({.*);<\/script>/m,
                  json = JSON.parse(regex.exec(html)[1]),
                  edges = json.entry_data.ProfilePage[0].graphql.user.edge_owner_to_timeline_media.edges;
              $.each(edges, function(n, edge) {
                   if (n <= 7){
                     var node = edge.node;
                    $('.img_ins').append('<a href="https://instagr.am/p/'+node.shortcode+'" target="_blank"><img src="'+node.thumbnail_src+'" width="150"></a>');
                   }
              });
            }
        });
    }); 
    </script>

1

Нижній код nodejs викреслює популярні зображення зі сторінки Instagram. Функція "ScrapeInstagramPage" забезпечує ефект після старіння.

var request = require('parse5');
var request = require('request');
var rp      = require('request-promise');
var $       = require('cheerio'); // Basically jQuery for node.js 
const jsdom = require("jsdom");    
const { JSDOM } = jsdom;


function ScrapeInstagramPage (args) {
    dout("ScrapeInstagramPage for username -> " + args.username);
    var query_url = 'https://www.instagram.com/' + args.username + '/';

    var cookieString = '';

    var options = {
        url: query_url,
        method: 'GET',
        headers: {
            'x-requested-with' : 'XMLHttpRequest',
            'accept-language'  : 'en-US,en;q=0.8,pt;q=0.6,hi;q=0.4', 
            'User-Agent'       : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
            'referer'          : 'https://www.instagram.com/dress_blouse_designer/',
            'Cookie'           : cookieString,
            'Accept'           : '*/*',
            'Connection'       : 'keep-alive',
            'authority'        : 'www.instagram.com' 
        }
    };


    function dout (msg) {
        if (args.debug) {
            console.log(msg);
        }
    }

    function autoParse(body, response, resolveWithFullResponse) {
        // FIXME: The content type string could contain additional values like the charset. 
        // Consider using the `content-type` library for a robust comparison. 
        if (response.headers['content-type'] === 'application/json') {
            return JSON.parse(body);
        } else if (response.headers['content-type'] === 'text/html') {
            return $.load(body);
        } else {
            return body;
        }
    }

    options.transform = autoParse;


    rp(options)
        .then(function (autoParsedBody) {
            if (args.debug) {
                console.log("Responce of 'Get first user page': ");
                console.log(autoParsedBody);
                console.log("Creating JSDOM from above Responce...");
            }

            const dom = new JSDOM(autoParsedBody.html(), { runScripts: "dangerously" });
            if (args.debug) console.log(dom.window._sharedData); // full data doc form instagram for a page

            var user = dom.window._sharedData.entry_data.ProfilePage[0].user;
            if (args.debug) {
                console.log(user); // page user
                console.log(user.id); // user ID
                console.log(user.full_name); // user full_name
                console.log(user.username); // user username
                console.log(user.followed_by.count); // user followed_by
                console.log(user.profile_pic_url_hd); // user profile pic
                console.log(autoParsedBody.html());
            }

            if (user.is_private) {
                dout ("User account is PRIVATE");
            } else {
                dout ("User account is public");
                GetPostsFromUser(user.id, 5000, undefined);
            }
        })
        .catch(function (err) {
            console.log( "ERROR: " + err );
        });  

    var pop_posts = [];
    function GetPostsFromUser (user_id, first, end_cursor) {
        var end_cursor_str = "";
        if (end_cursor != undefined) {
            end_cursor_str = '&after=' + end_cursor;
        }

        options.url = 'https://www.instagram.com/graphql/query/?query_id=17880160963012870&id=' 
                        + user_id + '&first=' + first + end_cursor_str;

        rp(options)
            .then(function (autoParsedBody) {
                if (autoParsedBody.status === "ok") {
                    if (args.debug) console.log(autoParsedBody.data);
                    var posts = autoParsedBody.data.user.edge_owner_to_timeline_media;

                    // POSTS processing
                    if (posts.edges.length > 0) {
                        //console.log(posts.edges);
                        pop_posts = pop_posts.concat
                        (posts.edges.map(function(e) {
                            var d = new Date();
                            var now_seconds = d.getTime() / 1000;

                            var seconds_since_post = now_seconds - e.node.taken_at_timestamp;
                            //console.log("seconds_since_post: " + seconds_since_post);

                            var ageing = 10; // valuses (1-10]; big value means no ageing
                            var days_since_post = Math.floor(seconds_since_post/(24*60*60));
                            var df = (Math.log(ageing+days_since_post) / (Math.log(ageing)));
                            var likes_per_day = (e.node.edge_liked_by.count / df);
                            // console.log("likes: " + e.node.edge_liked_by.count);
                            //console.log("df: " + df);
                            //console.log("likes_per_day: " + likes_per_day);
                            //return (likes_per_day > 10 * 1000);
                            var obj = {};
                            obj.url = e.node.display_url;
                            obj.likes_per_day = likes_per_day;
                            obj.days_since_post = days_since_post;
                            obj.total_likes = e.node.edge_liked_by.count;
                            return obj;
                        }
                        ));

                        pop_posts.sort(function (b,a) {
                          if (a.likes_per_day < b.likes_per_day)
                            return -1;
                          if (a.likes_per_day > b.likes_per_day)
                            return 1;
                          return 0;
                        });

                        //console.log(pop_posts);

                        pop_posts.forEach(function (obj) {
                            console.log(obj.url);
                        });
                    }

                    if (posts.page_info.has_next_page) {
                        GetPostsFromUser(user_id, first, posts.page_info.end_cursor);
                    }
                } else {
                    console.log( "ERROR: Posts AJAX call not returned good..." );
                }
            })
            .catch(function (err) {
                console.log( "ERROR: " + err );
            }); 
    }
}


ScrapeInstagramPage ({username : "dress_blouse_designer", debug : false});

Спробуйте тут

Приклад: для вказаної URL-адреси " https://www.instagram.com/dress_blouse_designer/ " можна викликати функцію

ScrapeInstagramPage ({username : "dress_blouse_designer", debug : false});

Я можу бачити лише перші 12 публікацій, як я можу їх отримати?
rahul gawale

0

Це працює за допомогою простого ajax виклику та ітераційного контуру зображення.

        var name = "nasa";
        $.get("https://www.instagram.com/" + name + "/?__a=1", function (data, status) {
            console.log('IG_NODES', data.user.media.nodes);
            $.each(data.user.media.nodes, function (n, item) {
                console.log('ITEMS', item.display_src);
                $('body').append(
                    "<div class='col-md-4'><img class='img-fluid d-block' src='" + item.display_src + "'></div>"
                );
            });
        })

Це працювало для мене, але лише тоді, коли я ввійшов в Instagram.
зунді

-1

Ось php-скрипт, який завантажує зображення та створює HTML-файл із посиланнями на зображення. Кредит 350D для PHP-версії, це лише детально розроблено. Я б запропонував поставити це на роботу в крон і звільнити, проте часто потрібно. Перевірено, працюючи станом на травень 2019 року .

<?
$user = 'smena8m';
$igdata = file_get_contents('https://instagram.com/'.$user.'/');
preg_match('/_sharedData = ({.*);<\/script>/',$igdata,$matches);
$profile_data = json_decode($matches[1])->entry_data->ProfilePage[0]->graphql->user;
$html = '<div class="instagramBox" style="display:inline-grid;grid-template-columns:auto auto auto;">';
$i = 0;
$max = 9;
while($i<$max){
    $imglink = $profile_data->edge_owner_to_timeline_media->edges[$i]->node->shortcode;
    $img = $profile_data->edge_owner_to_timeline_media->edges[$i]->node->thumbnail_resources[0]->src;
    file_put_contents('ig'.$i.'.jpg',file_get_contents($img));
    $html .= '<a href="https://www.instagram.com/p/'.$imglink.'/" target="_blank"><img src="ig'.$i.'.jpg" /></a>';
    $i++;
}
$html .= '</div>';
$instagram = fopen('instagram.html','w');
fwrite($instagram,$html);
fclose($instagram);
?>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.