Come posso ottenere i media di un utente da Instagram senza autenticarsi come utente?

Sto provando a inserire i contenuti multimediali recenti di un utente su una barra laterale. Sto cercando di utilizzare l’API di Instagram per recuperare i file multimediali.

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

La documentazione dice di OTTENERE https://api.instagram.com/v1/users//media/recent/ , ma dice di passare un token di accesso OAuth. Un token di accesso rappresenta l’authorization ad agire per conto di un utente. Non voglio che gli utenti accedano a Instagram per vederlo nella barra laterale. Non dovrebbero nemmeno avere bisogno di avere un account Instagram.

Per esempio, posso andare su http://instagram.com/thebrainscoop senza essere loggato su Instagram e vedere le foto. Voglio farlo attraverso l’API.

Nell’API di Instagram, le richieste non autenticate dall’utente passano un client_id invece di un access_token . Se ci provo, però, ottengo:

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

Quindi, questo non è ansible? Non c’è modo di recuperare i contenuti multimediali (pubblici) più recenti di un utente senza chiedere ad un utente di accedere prima a un account Instagram tramite OAuth?

È tardi, ma vale la pena se aiuta qualcuno come non l’ho visto nella documentazione di Instagram.

Per eseguire GET su https://api.instagram.com/v1/users//media/recent/ (al momento attuale della scrittura) in realtà non hai bisogno del token di accesso OAuth.

È ansible eseguire https://api.instagram.com/v1/users/[USER ID]/media/recent/?client_id=[CLIENT ID]

[ID CLIENTE] sarebbe un ID cliente valido registrato nell’app tramite i client di gestione (non correlato all’utente di sorta). Puoi ottenere [USER ID] dal nome utente eseguendo la richiesta di ricerca degli utenti 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( $('', { 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; } 
  

2017/11/11
Poiché Instagram ha cambiato il modo in cui forniscono questi dati, nessuno dei metodi sopra descritti funziona oggigiorno. Ecco il nuovo modo di ottenere i media dell’utente:
OTTIENI https://instagram.com/graphql/query/?query_id=17888483320059182&variables={"id":"1951415043","first":20,"after":null}
Dove:
query_id – valore permanente: 17888483320059182 (nota che potrebbe essere modificato in futuro).
id -id dell’utente. Potrebbe venire con un elenco di utenti. Per ottenere l’elenco degli utenti puoi utilizzare la seguente richiesta: GET https://www.instagram.com/web/search/topsearch/?context=blended&query=YOUR_QUERY
first – quantità di articoli da ottenere.
after – id dell’ultimo elemento se si desidera ottenere elementi da tale id.

A partire dalla scorsa settimana, Instagram disabilitato /media/ urls, ho implementato una soluzione alternativa, che funziona abbastanza bene per ora.

Per risolvere i problemi di tutti in questo thread, ho scritto questo: https://github.com/whizzzkid/instagram-reverse-proxy

Fornisce tutti i dati pubblici di instagram utilizzando i seguenti endpoint:

Ottieni media utente:

 https://igapi.ga//media eg: https://igapi.ga/whizzzkid/media 

Ottieni contenuti multimediali dell’utente con il conteggio dei limiti:

 https://igapi.ga//media?count=N // 1 < N < 20 eg: https://igapi.ga/whizzzkid/media?count=5 

Usa JSONP:

 https://igapi.ga//media?callback=foo eg: https://igapi.ga/whizzzkid/media?callback=bar 

L'API proxy aggiunge anche la pagina successiva e gli URL delle pagine precedenti alla risposta, quindi non è necessario calcolarla alla fine.

Ragazzi, spero che vi piaccia!

Grazie a @ 350D per avvistare questo 🙂

Sono stato in grado di ottenere i media più recenti di un utente utilizzando la seguente API senza autenticazione (compresa la descrizione, i Mi piace, il conteggio dei commenti).

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

Per esempio

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

L’API di Instagram richiede l’autenticazione dell’utente tramite OAuth per accedere all’endpoint multimediale recente per un utente. Non sembra che ci sia un altro modo in questo momento per ottenere tutti i media per un utente.

Se stai cercando un modo per generare un token di accesso da utilizzare su un singolo account, puoi provare questo -> https://coderwall.com/p/cfgneq .

Avevo bisogno di un modo per usare l’API di Instagram per afferrare tutti i media più recenti per un particolare account.

Ecco le soluzioni per i binari. È una specie di back-door, che in realtà è la porta d’ingresso.

 # 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 

L’object che si riceve varia a seconda che si tratti di una ricerca utente o di una ricerca di tag. Ottengo i dati in questo modo:

 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 

Quindi ottengo un’altra pagina di risultati costruendo un URL nel modo seguente:

  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' 

Grazie allo schema API in continua evoluzione (e progettato in modo orribile) di Instagram, la maggior parte di questi non funzionerà più a partire da aprile 2018.

Ecco l’ultimo percorso per accedere ai dati dei singoli post se stai interrogando direttamente la loro API utilizzando il metodo https://www.instagram.com/username/?__a=1 .

Supponendo che i dati JSON restituiti siano dati $data è ansible eseguire il ciclo di ogni risultato utilizzando i seguenti esempi di percorso:

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

Le cose principali in questo recente cambiamento sono state graphql e edge_owner_to_timeline_media .

Sembra che stiano per uccidere questo accesso API per i clienti non “business” nel DEC 2018, quindi sfruttale al massimo.

Spero che aiuti qualcuno;)

Voglio solo aggiungere alla risposta @ 350D, poiché è stato difficile per me capire.

La mia logica nel codice è la prossima:

Quando chiami l’API per la prima volta, sto chiamando solo https://www.instagram.com/_vull_ /media/ . Quando ricevo risposta, controllo il valore booleano di more_available . Se è vero, ottengo l’ultima foto dall’array, ottengo il suo id e poi richiama di nuovo l’API di Instagram, ma questa volta https://www.instagram.com/_vull_/media/?max_id=1400286183132701451_1642962433 .

Cosa importante da sapere qui, questo Id è l’Id dell’ultima immagine dell’array. Quindi quando chiedi il maxId con l’ultimo id dell’immagine nell’array, otterrai le 20 foto successive, e così via.

Spero che questo chiarisca le cose.

Se bypassassi Oauth probabilmente non sapresti quale utente di instagram sono. Detto questo, ci sono alcuni modi per ottenere immagini di instagram senza autenticazione.

  1. L’API di Instagram ti consente di visualizzare le immagini più popolari di un utente senza autenticazione. Utilizzando il seguente endpoint: Ecco il link

  2. Instagram fornisce feed RSS per i tag a questo .

  3. Le pagine utente di Instagram sono pubbliche, quindi puoi usare PHP con CURL per ottenere la loro pagina e un parser DOM per cercare nell’html i tag immagine che desideri.

Ancora un trucco, cerca le foto con gli hashtag:

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

Dove:

query_hash – valore permanente (credo che il suo hash di 17888483320059182, possa essere modificato in futuro)

tag_name : il titolo parla da solo

first – quantità di elementi da ottenere (non so perché, ma questo valore non funziona come previsto. Il numero effettivo di foto restituite è leggermente superiore al valore moltiplicato per 4,5 (circa 110 per il valore 25 e circa 460 per il valore 100))

after – id dell’ultimo elemento se si desidera ottenere elementi da tale id. Il valore di end_cursor dalla risposta JSON può essere utilizzato qui.

Bene, dato che /?__a=1 smesso di funzionare, è meglio usare curl e analizzare la pagina di instagram come scritto in questa risposta: Generare l’API di Instagram dei token di accesso, senza dover effettuare il login?

Aggiornare

Questo metodo non funziona più

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 = "
  • "; $("ul.instagram").append(data_li); } }); }); });
  • HTML:

     

    CSS:

     ul.instagram { list-style: none; } ul.instagram li { float: left; } ul.instagram li img { height: 100px; } 

    Il codice nodejs inferiore scarica le immagini più popolari da una pagina Instagram. La funzione ‘ScrapeInstagramPage’ si occupa dell’effetto post invecchiamento.

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

    Provalo qui

    Esempio: dato un URL ” https://www.instagram.com/dress_blouse_designer/ ” si può chiamare la funzione

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

    Funziona utilizzando una semplice chiamata ajax e iterando percorsi di immagine.

      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( "
    " ); }); })

    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 = "
  • "; $("ul.instagram").append(data_li); } }); }); });
  • campione funzionante