Comment puis-je obtenir les médias d'un utilisateur d'Instagram sans m'authentifier en tant qu'utilisateur?

175

J'essaie de mettre les médias Instagram récents d'un utilisateur sur une barre latérale. J'essaie d'utiliser l'API Instagram pour récupérer les médias.

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

La documentation dit à GET https://api.instagram.com/v1/users/<user-id>/media/recent/, mais elle dit de passer un jeton d'accès OAuth. Un jeton d'accès représente l'autorisation d'agir au nom d'un utilisateur. Je ne veux pas que les utilisateurs se connectent à Instagram pour voir cela dans la barre latérale. Ils ne devraient même pas avoir besoin d'un compte Instagram.

Par exemple, je peux aller sur http://instagram.com/thebrainscoop sans être connecté à Instagram et voir des photos. Je veux faire cela via l'API.

Dans l'API Instagram, les demandes non-utilisateurs authentifiés passent un au client_idlieu d'un access_token. Si j'essaye cela, cependant, j'obtiens:

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

Alors, n'est-ce pas possible? N'existe-t-il aucun moyen de récupérer les derniers médias (publics) d'un utilisateur sans demander à un utilisateur de se connecter d'abord à un compte Instagram via OAuth?

Peeja
la source
C'est possible avec ce plugin, il suffit de consulter le code source de la façon dont ils ont récupéré les derniers médias publics d'un utilisateur sans demander à un utilisateur de se connecter à son compte instagram. : D smashballoon.com/instagram-feed/demo Vous avez juste besoin d'un identifiant client, aucun jeton d'accès n'est nécessaire. : D
jehzlau
Vous devez vous authentifier pour qu'ils puissent vous suivre et limiter vos téléchargements (tarifs ...) comme toutes les grandes API. Il y a du public pour les vrais utilisateurs et du public pour les scrappers / bots, ce qui n'est généralement pas le même que les vrais utilisateurs verront des publicités et utiliseront directement le service.
Christophe Roussy
1
Aucune de ces méthodes ne fonctionne plus. Voir stackoverflow.com/questions/49852080/…
Moradnejad

Réponses:

123

C'est tard, mais ça vaut le coup si cela aide quelqu'un car je ne l'ai pas vu dans la documentation d'Instagram.

Pour exécuter GET sur https://api.instagram.com/v1/users/<user-id>/media/recent/(au moment de l'écriture actuelle), vous n'avez en fait pas besoin de jeton d'accès OAuth.

Vous pouvez effectuer https://api.instagram.com/v1/users/[USER ID]/media/recent/?client_id=[CLIENT ID]

[ID CLIENT] serait un identifiant client valide enregistré dans l'application via la gestion des clients (sans aucun lien avec l'utilisateur). Vous pouvez obtenir [USER ID] à partir du nom d'utilisateur en effectuant la demande de recherche des utilisateurs GET: https://api.instagram.com/v1/users/search?q=[USERNAME]&client_id=[CLIENT ID]

Ersan J Sano
la source
9
Je pense qu'ils ont peut-être changé d'avis à nouveau. J'obtiens la même réponse d'erreur que celle indiquée dans l'OP
James
35
Ceci n'est valable que sur les applications créées avant le 17 novembre 2015 et ne sera plus pris en charge après juin 2016. Après cela, vous aurez besoin d'un oauth access_token. instagram.com/developer/changelog
Dax Fohl
211
C'est tellement stupide et irritant. Pourquoi forceraient-ils un jeton d'accès simplement à afficher des images qui sont déjà publiques ? J'essaye à peine de les rincer pour chaque utilisateur dans le monde, je veux juste afficher la dernière insta d'un client sans avoir à passer des heures à jouer avec. Gah!
Matt Fletcher
8
Limites de débit @Cabus, mec.
Walf
20
@MattFletcher c'est encore plus stupide maintenant, il faut passer par l'examen des autorisations de l'application, et ne pas savoir si c'est même faisable puisque ce cas d'utilisation "afficher le propre flux du client dans sa propre page Web" n'est pas l'un des cas d'utilisation. Duh, ces restrictions sont nulles.
Ciantic
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>

Vous pouvez télécharger n'importe quel flux de photos d'utilisateurs Instagram au format JSON en utilisant à ?__a=1côté de l'adresse de la page de destination comme celle-ci . Pas besoin d'obtenir un identifiant d'utilisateur ou d'enregistrer une application, pas de jetons, pas d'oAuth.

min_idet les max_idvariables peuvent être utilisées pour la pagination, voici un exemple

YQLpeut ne pas fonctionner ici dans l'iframe découpé, vous pouvez donc toujours le vérifier manuellement dans YQL Console

MISE À JOUR D'AVRIL 2018: Après les dernières mises à jour d'Instagram, vous ne pouvez pas le faire côté client (javascript) car les en-têtes personnalisés pour la demande signée ne peuvent pas être définis avec JavaScript en raison de CORS Access-Control-Allow-Headersrestrictions. Il reste possible de le faire via phpou toute autre méthode côté serveur avec la signature appropriée en fonction de rhx_gis, csrf_tokenet les paramètres de demande. Vous pouvez en savoir plus ici .

MISE À JOUR DE JANVIER 2019: YQL a pris sa retraite, alors, vérifiez ma dernière mise à jour avec Google Image Proxy comme CORSproxy pour la page Instagram! Ensuite, seul moment négatif - la pagination n'est pas disponible avec cette méthode.

PHP Solution:

    $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;
350D
la source
14
@ 350D Comment avez-vous trouvé cela? Je ne le trouve nulle part dans leur documentation. Je veux juste en savoir plus sur ce qui est possible avec ce point de terminaison (EG images carrées vs non carrées, si cela prévoit de se terminer en juin, etc.) - Merci!
Phil Johnston
8
@Phil Johnston Juste une recherche 😀 Prenez-en une autre - vous pouvez ajouter / media /? Size = L à côté de l'URL de la page de destination de la photo et obtenir une photo en résolution PLEINE.
350D du
9
@ user2659694 J'ai enfin trouvé la solution pour obtenir les pages suivantes avec cette méthode que vous pouvez utiliser / media /? max_id = [MAX_ID]
Reza
3
Pour info, cela ne semble fonctionner que si vous êtes vous-même connecté à un compte Instagram. Essayez de le faire dans Incognito dans Chrome ou similaire et vous verrez que la réponse JSON ne contient aucun élément. J'essayais d'incorporer cela dans un script pour obtenir la liste des URL sur un serveur Web et j'ai dû revenir aux anciennes méthodes d'autorisation.
Ryan Zink
9
@RyanZink essayiez-vous un compte privé? cela fonctionne bien pour moi déconnecté ou incognito sur les comptes publics.
ryan
41

11.11.2017
Depuis qu'Instagram a changé la façon dont ils fournissent ces données, aucune des méthodes ci-dessus ne fonctionne de nos jours. Voici la nouvelle façon d'obtenir les médias de l'utilisateur:
GET https://instagram.com/graphql/query/?query_id=17888483320059182&variables={"id":"1951415043","first":20,"after":null}
Où:
query_id- valeur permanente: 17888483320059182 (notez qu'elle pourrait être modifiée à l'avenir).
id- id de l'utilisateur. Il peut venir avec une liste d'utilisateurs. Pour obtenir la liste des utilisateurs, vous pouvez utiliser la requête suivante: GET https://www.instagram.com/web/search/topsearch/?context=blended&query=YOUR_QUERY
first- quantité d'articles à obtenir.
after- id du dernier élément si vous souhaitez obtenir des éléments à partir de cet identifiant.

Footniko
la source
Pourriez-vous s'il vous plaît me faire savoir d'où obtenir le query_id et l'identifiant de l'utilisateur?
Vijaysinh Parmar
2
@VijaysinhParmar, comme je l'ai mentionné, query_idest une valeur permanente. Cela signifie qu'il s'agit toujours de 17888483320059182 (du moins à moins qu'Instagram ne le modifie). id de l'utilisateur - est l'id de l'utilisateur (modifié un peu ma réponse)
Footniko
1
Je ne me souviens pas exactement, quelque part sur Internet. Mais je n'ai aucune relation avec Instagram, donc au cas où ça changerait, je ne pourrai pas vous dire le nouveau :(
Footniko
1
Vous vous demandez quelle est la politique de limitation des taux de cette approche?
kkzxak47
1
Si quelqu'un a des problèmes pour demander cette URL via une requête CURL, vous devez obtenir l'en-tête de la demande de cookie (ouvrez l'onglet Réseaux, après avoir exécuté l'URL, copiez l'en-tête du cookie et collez-le dans l'en-tête de la requête curl. Si vous ne le faites pas, vous obtiendrez une erreur d'accès refusé 403).
Anders
39

J'ai pu obtenir les médias les plus récents d'un utilisateur en utilisant l'API suivante sans authentification (y compris la description, les likes, le nombre de commentaires).

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

Par exemple

https://www.instagram.com/{username}/?__a=1
Michael
la source
1
cela a également fonctionné pour moi.Mais quand "is_video = true", aucune URL vidéo dans les données.
didikee
4
Bien, vous ne pouvez obtenir que les vignettes (pas la vidéo elle-même) - malheureusement, je n'ai trouvé aucune documentation officielle pour cela et je n'ai aucune idée si cette API est obsolète ou combien de temps elle sera prise en charge.
Michael
8
Depuis le 13/04/2018, cela ne semble plus fonctionner. Peut-être à cause du dernier scandale des données de Cambridge Analytica sur Facebook, ils resserrent énormément les choses. Avez-vous d'autres suggestions pour obtenir des données utilisateur de base sans authentification?
BakerStreetSystems
2
Oui, il fut un temps où cette API ne fonctionnait pas - Mais maintenant elle est de retour
Michael
4
Cela a fonctionné pour moi, mais uniquement lorsque je suis connecté à Instagram.
zundi
16

Depuis la semaine dernière, Instagram a désactivé les /media/URL, j'ai mis en œuvre une solution de contournement, qui fonctionne plutôt bien pour le moment.

Pour résoudre les problèmes de tout le monde dans ce fil, j'ai écrit ceci: https://github.com/whizzzkid/instagram-reverse-proxy

Il fournit toutes les données publiques d'Instagram en utilisant les points de terminaison suivants:

Obtenez le média utilisateur:

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

Obtenez le média utilisateur avec un nombre limité:

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

Utilisez JSONP:

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

L'API proxy ajoute également les URL de la page suivante et de la page précédente à la réponse afin que vous n'ayez pas besoin de calculer cela de votre côté.

J'espère que vous l'aimez!

Merci à @ 350D pour l'avoir repéré :)

whizzzkid
la source
1
@rex jusqu'à ce qu'ils changent la façon dont les choses fonctionnent à leur fin, nous sommes bons! Ils ne se sont pas dérangés au cours des 3 dernières années, probablement pas dans les 3 prochaines.
whizzzkid
3
@whizzzkid Pas de chance, ils le changent. J'ai vu que vous pensez que le point de terminaison de l'utilisateur fera les choses, mais il y a des limites pour les demandes pour les utilisateurs non connectés. Des idées?
nobilik
1
@nobilik la solution de contournement est en place, igpi.ga/whizzzkid/media?count=3 et igpi.ga/graphql/query/?user_id=1606740656&count=3 devraient tous deux vous renvoyer des données. N'oubliez pas que les référents non définis sont désactivés pour ces URL.
whizzzkid
1
@whizzzkid - Ça marche! Merci beaucoup - vous êtes un érudit et un gentleman!
James Trickey
1
J'obtiens une erreur "L'accès a été refusé au référent". Peut-être que cela ne fonctionne plus?
khalid13
14

L'API Instagram nécessite une authentification de l'utilisateur via OAuth pour accéder au point de terminaison multimédia récent d'un utilisateur. Il ne semble pas y avoir d'autre moyen pour le moment d'obtenir tous les médias pour un utilisateur.

Bill Rollins
la source
4
Cela n'a aucun sens, si je veux afficher mes propres médias sur mon propre site Web, pourquoi ai-je besoin que tous ceux qui veulent le voir aient un compte Instagram?
ninjasense
5
ninjasense - Je ne pense pas que ce soit ainsi que cela fonctionne. Je pense que votre site Web devrait contenir un peu de code qui interrogerait l'API Instagram avec vos informations d'identification oauth fournies pour extraire vos médias. Vous montriez ensuite vos médias à tous les utilisateurs de votre site. Votre site serait la seule chose qui aurait besoin de s'authentifier avec Instagram.
Bill Rawlinson
9

Si vous cherchez un moyen de générer un jeton d'accès à utiliser sur un seul compte, vous pouvez essayer ceci -> https://coderwall.com/p/cfgneq .

J'avais besoin d'un moyen d'utiliser l'api instagram pour récupérer tous les derniers médias pour un compte particulier.

Craig Heneveld
la source
5
C'est plus ou moins ce que j'ai fait à la fin: créer un nouveau compte, créer un jeton d'accès et stocker ce jeton dans la configuration de mon serveur à côté de la clé API. Cependant, c'est une mauvaise solution pour les applications JS, car elle nécessite l'envoi de votre jeton d'accès à l'utilisateur (ce que j'ai vu de nombreux exemples de code faire). Heureusement pour moi, je peux le faire côté serveur.
Peeja
4
@CraigHeneveld Comment faites-vous pour garder hat access_token à jour? N'a-t-il pas expiré sur vous?
Ryan Ore
Le jeton expire-t-il un certain temps?
Monitus
Si ma mémoire est bonne, la clé n'expire que si vous modifiez votre mot de passe. Voici un autre fil de discussion sur la question -> stackoverflow.com/questions/22753170/…
Craig Heneveld
Comment pouvons-nous obtenir plusieurs photos d'utilisateurs? Par exemple, pouvons-nous passer plusieurs identifiants d'utilisateur séparés par ","?
Aadil Keshwani
9

Voici une des solutions de rails. C'est une sorte de porte dérobée, qui est en fait la porte d'entrée.

# 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'objet que vous récupérez varie selon qu'il s'agit ou non d'une recherche d'utilisateur ou d'une recherche de balises. J'obtiens les données comme ceci:

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

J'obtiens ensuite une autre page de résultats en construisant une URL de la manière suivante:

  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'
Benjamin Talisman
la source
cette solution fonctionne pour moi, mais j'ai quelques problèmes avec elle. Après avoir chargé les données, mon serveur rails (utilisant Rails 5.0.0, serveur Puma 3.6.0) redémarre inexplicablement ... Une solution possible?
Luis Eduardo Rojas Cabrera
8

Grâce au schéma d'API en constante évolution (et horriblement conçu) d'Instagram, la plupart des éléments ci-dessus ne fonctionneront plus à partir d'avril 2018.

Voici le dernier chemin d'accès pour accéder aux données de publication individuelles si vous interrogez leur API directement à l'aide de la https://www.instagram.com/username/?__a=1méthode.

En supposant que vos JSONdonnées renvoyées soient, $datavous pouvez parcourir chaque résultat en utilisant les exemples de chemin suivants:

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

Les principaux éléments de ce changement récent étaient graphqlet edge_owner_to_timeline_media.

On dirait qu'ils vont supprimer cet accès à l'API pour les clients non `` professionnels '' en décembre 2018, alors profitez-en autant que vous le pouvez.

J'espère que ça aide quelqu'un;)

pimenter
la source
Cela m'a juste aidé, je veux juste montrer les derniers messages Instagram pour un client. Merci!
weston deboer
1
instagram.com/username/?__a=1 donne maintenant une erreur: L'accès à www.instagram.com a été refusé Vous n'avez pas l'autorisation de voir cette page. HTTP ERROR 403 d'autres idées?
Hese
1
Oui, Instagram a maintenant tué cela. «Pour améliorer continuellement la confidentialité et la sécurité des utilisateurs d'Instagram, nous accélérons la dépréciation de la plate-forme d'API d'Instagram, en apportant immédiatement les modifications suivantes. Nous comprenons que cela peut affecter votre entreprise ou vos services, et nous apprécions votre soutien pour assurer la sécurité de notre plate-forme. Ces fonctionnalités seront désactivées immédiatement (précédemment définies pour le 31 juillet 2018 ou la dépréciation du 11 décembre 2018). "
Spice
Si ce que je lis est correct, il ne sera plus possible de récupérer des images ou des données à partir d'un compte "non professionnel". Ils tuent totalement l'API de la plate-forme. Je suppose que c'est alors ... instagram.com/developer/changelog
épice
1
@james_tookey ne sera pas possible. En raison de leurs nouvelles restrictions de confidentialité, il ne sera plus en mesure d'interroger ou de récupérer les utilisateurs / données des comptes personnels, uniquement ceux des entreprises. Fondamentalement, ils ont juste tué toute utilisation de l'API pour les comptes personnels.
épice
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;
}
Leo
la source
5

Je veux juste ajouter à la réponse @ 350D, car c'était difficile pour moi de comprendre.

Ma logique dans le code est la suivante:

Lorsque j'appelle l'API pour la première fois, j'appelle uniquement https://www.instagram.com/_vull_ /media/. Lorsque je reçois une réponse, je vérifie la valeur booléenne de more_available. Si c'est vrai, j'obtiens la dernière photo du tableau, j'obtiens son identifiant, puis j'appelle à nouveau l'API Instagram, mais cette fois https://www.instagram.com/_vull_/media/?max_id=1400286183132701451_1642962433.

Chose importante à savoir ici, cet identifiant est l'identifiant de la dernière image du tableau. Ainsi, lorsque vous demandez maxId avec le dernier identifiant de l'image dans le tableau, vous obtiendrez les 20 prochaines images, et ainsi de suite.

J'espère que cela clarifiera les choses.

Vulovic Vukasin
la source
4

Si vous contournez Oauth, vous ne saurez probablement pas de quel utilisateur Instagram il s'agit. Cela étant dit, il existe plusieurs façons d'obtenir des images Instagram sans authentification.

  1. L'API d'Instagram vous permet de visualiser les images les plus populaires d'un utilisateur sans authentification. En utilisant le point de terminaison suivant: voici le lien

  2. Fournit des flux rss instagram pour les balises à cette .

  3. Les pages utilisateur d'Instagram sont publiques, vous pouvez donc utiliser PHP avec CURL pour obtenir leur page et un analyseur DOM pour rechercher dans le html les balises d'image que vous souhaitez.

Dorian Damon
la source
9
Semble désuet.
Burak Tokak
est-il possible de contourner l'authentification pour instagram
JAck
3

Encore une astuce, recherchez les photos par hashtags:

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

Où:

query_hash - valeur permanente (je crois que son hachage de 17888483320059182, peut être changé à l'avenir)

tag_name - Le titre parle de lui-même

first - quantité d'articles à obtenir (je ne sais pas pourquoi, mais cette valeur ne fonctionne pas comme prévu. Le nombre réel de photos renvoyées est légèrement supérieur à la valeur multipliée par 4,5 (environ 110 pour la valeur 25, et environ 460 pour la valeur valeur 100))

after- id du dernier élément si vous souhaitez obtenir des éléments à partir de cet identifiant. La valeur de la end_cursorréponse JSON peut être utilisée ici.

kara4k
la source
Comment trouvez-vous cela?
ekntrtmz
3

Si vous souhaitez rechercher des utilisateurs sans avoir l'ID client et le jeton d'accès:

1: Si vous souhaitez rechercher tous les utilisateurs ayant vos noms similaires à votre mot de recherche:

remplacez SeachName par le texte que vous souhaitez rechercher:

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

2: si vous souhaitez rechercher exactement le même nom d'utilisateur:

remplacez UserName par votre nom de recherche souhaité:

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

Rahul Gusain
la source
2

Vous pouvez utiliser cette API pour récupérer les informations publiques de l'utilisateur instagram:
https://api.lityapp.com/instagrams/thebrainscoop?limit=2

Si vous ne définissez pas le paramètre limite, les messages sont limités à 12 par défaut

Cette api a été créé dans SpringBoot avec HtmlUnit comme vous pouvez le voir dans le code:

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


C'est un exemple de réponse:

{
  "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
        }
      ]
    }
  ]
}
Ruan Barroso
la source
puis-je obtenir des données par userid (pk)
SAURABH RATHOD
Désolé @SAURABHRATHOD J'ai essayé mais je n'ai pas trouvé de moyen de le faire. Je serais très heureux si quelqu'un résout ce problème. Merci pour le commentaire.
Ruan Barroso
2

J'avais vraiment besoin de cette fonction mais pour Wordpress. Je m'adapte et cela a parfaitement fonctionné

<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>
Karra Max
la source
1

Le code nodejs ci-dessous extrait les images populaires d'une page Instagram. La fonction «ScrapeInstagramPage» prend en charge l'effet post-vieillissement.

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

Essayez-le ici

Exemple: Pour une URL ' https://www.instagram.com/dress_blouse_designer/ ', on peut appeler la fonction

ScrapeInstagramPage ({username : "dress_blouse_designer", debug : false});
Vishnu Kanwar
la source
Je ne peux voir que les 12 premiers messages, comment puis-je les obtenir tous?
rahul gawale
0

Cela fonctionne en utilisant un simple appel ajax et des chemins d'image itératifs.

        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>"
                );
            });
        })
Evin Weissenberg
la source
Cela a fonctionné pour moi, mais uniquement lorsque je suis connecté à Instagram.
zundi
-1

Voici un script php qui télécharge les images et crée un fichier html avec des liens sur les images. Crédit 350D pour la version php, ceci est juste élaboré .. Je suggérerais de mettre ceci est un travail cron et de tirer aussi souvent que vous en avez besoin. Vérifié fonctionnant en mai 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);
?>
bave
la source