Как я могу получить медиа пользователя из Instagram без аутентификации в качестве пользователя?


Я пытаюсь поместить последние медиа Instagram пользователя на боковой панели. Я пытаюсь использовать API Instagram для извлечения информации.

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

в документации говорится, чтобы получить https://api.instagram.com/v1/users/<user-id>/media/recent/, но он говорит, чтобы передать маркер доступа OAuth. Маркер доступа представляет собой разрешение действовать от имени пользователя. Я не хочу, чтобы пользователи входили в Instagram, чтобы увидеть это на боковой панели. Они даже не должны иметь Аккаунт в Instagram.

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

в API Instagram запросы, не прошедшие проверку подлинности пользователя, передают client_id вместо 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?

17 146

17 ответов:

Это поздно, но стоит, если это помогает кому-то, как я не видел его в документации Instagram.

для выполнения GET on 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]

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

var name = "smena8m",
  items;
$.getJSON("https://query.yahooapis.com/v1/public/yql", {
  q: "select * from json where url='https://www.instagram.com/" + name + "/?__a=1'",
  format: "json",
  _: name
}, function(data) {
  console.log(data);
  if (data.query.results) {
    items = data.query.results.json.user.media.nodes;
    $.each(items, function(n, item) {
      $('body').append(
        $('<a/>', {
          href: 'https://www.instagram.com/p/'+item.code,
          target: '_blank'
        }).css({
          backgroundImage: 'url(' + item.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 обновление: после последних обновлений instagram вы не можете сделать это на стороне клиента (javascript), потому что пользовательские заголовки для подписанного запроса не могут быть установлены с помощью javascript из-за CORSAccess-Control-Allow-Headers ограничения. Это все еще можно сделать с помощью php или любой другой метод на стороне сервера с правильной подписью на основе rhx_gis,csrf_token и параметры запроса. Вы можете прочитать больше об этом здесь.

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;

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

по состоянию на прошлой неделе, Instagram отключен /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 для обнаружения этого :)

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

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

например.

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

API Instagram требует аутентификации пользователя через OAuth для доступа к последней конечной точке мультимедиа для пользователя. Там, кажется, не быть любой другой путь прямо сейчас, чтобы получить все средства массовой информации для пользователя.

Если вы ищете способ создания маркера доступа для использования в одной учетной записи, вы можете попробовать это -> https://coderwall.com/p/cfgneq.

Мне нужен был способ использовать api instagram, чтобы захватить все последние медиа для конкретной учетной записи.

вот рельсы решения. Это своего рода задняя дверь, которая на самом деле является передней дверью.

# 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'

благодаря постоянно меняющейся (и ужасающе разработанной) схеме API Instagram большинство из вышеперечисленных больше не будет работать с апреля 2018 года.

вот последний путь для доступа к отдельным данным post, если вы запрашиваете их 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 так что сделать большую часть его, пока вы можете.

надеюсь, что это поможет кому-то;)

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

моя логика в коде следующее:

при первом вызове API я вызываю только https://www.instagram.com/_vull_ /media/. Когда я получаю ответ, я проверяю логическое значение more_available. Если это правда, я получаю последнюю фотографию из массива, получаю ее идентификатор, а затем снова вызываю API Instagram, но на этот раз https://www.instagram.com/_vull_/media/?max_id=1400286183132701451_1642962433.

здесь важно знать, что этот идентификатор является идентификатором последнего изображения в массиве. Поэтому, когда вы просите maxId с последним идентификатором изображения в массиве, вы получите следующие 20 фотографий, и так далее.

надеюсь, это прояснит ситуацию.

Если вы обходите Oauth, вы, вероятно, не знаете, какой пользователь instagram они есть. При этом есть несколько способов получить изображения instagram без аутентификации.

  1. API Instagram позволяет просматривать самые популярные изображения пользователя без аутентификации. Используя следующую конечную точку:вот ссылка

  2. Instagram предоставляет RSS-каналы для тегов этой.

  3. пользователей Instagram страницы являются общедоступными, поэтому вы можете использовать PHP с CURL, чтобы получить свою страницу и парсер DOM для поиска html для тегов изображений, которые вы хотите.

еще один трюк, поиск фотографий по хештегу:

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 - идентификатор последнего элемента, если вы хотите получить товар с этим ID. Значение end_cursor от ответа JSON можно использовать здесь.

Ну как /?__a=1 перестала работать сейчас, лучше использовать curl и разобрать страницу instagram, как написано в этом ответе:создать маркер доступа Instagram API, без необходимости входа в систему?

обновление

этот метод больше не работает

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;
}

приведенный ниже код 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});

это работает с помощью простого вызова 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>"
                );
            });
        })

jsfiddle

    $(document).ready(function(){

    var username = "hadidapp";
    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);
            }
        });

    });
});

рабочий образец