¿Cómo puedo obtener los medios de un usuario de Instagram sin autenticarme como usuario?

175

Estoy tratando de poner los medios de Instagram recientes de un usuario en una barra lateral. Estoy tratando de usar la API de Instagram para buscar los medios.

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

La documentación le dice a GET https://api.instagram.com/v1/users/<user-id>/media/recent/, pero le dice que pase un token de acceso OAuth. Un token de acceso representa la autorización para actuar en nombre de un usuario. No quiero que los usuarios inicien sesión en Instagram para ver esto en la barra lateral. Ni siquiera deberían necesitar tener una cuenta de Instagram.

Por ejemplo, puedo ir a http://instagram.com/thebrainscoop sin haber iniciado sesión en Instagram y ver fotos. Quiero hacer eso a través de la API.

En la API de Instagram, las solicitudes no autenticadas por el usuario pasan un en client_idlugar de un access_token. Sin embargo, si lo intento, obtengo:

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

Entonces, ¿no es esto posible? ¿No hay forma de obtener los últimos medios (públicos) de un usuario sin pedirle primero que inicie sesión en una cuenta de Instagram a través de OAuth?

Peeja
fuente
Es posible con este complemento, solo revise el código fuente de cómo obtuvieron los últimos medios públicos de un usuario sin pedirle a un usuario que inicie sesión en su cuenta de instagram. : D smashballoon.com/instagram-feed/demo Solo necesita una identificación de cliente, no se necesita token de acceso. : D
jehzlau
Debe autenticar para que puedan rastrearlo y limitar sus descargas (tasas ...) como cualquier API grande. Hay público para usuarios reales y público para scrappers / bots, que generalmente no es lo mismo que los usuarios reales verán anuncios y usarán directamente el servicio.
Christophe Roussy
1
Ninguno de estos métodos funciona más. Ver stackoverflow.com/questions/49852080/…
Moradnejad

Respuestas:

123

Esto es tarde, pero vale la pena si ayuda a alguien, ya que no lo vi en la documentación de Instagram.

Para realizar GET en https://api.instagram.com/v1/users/<user-id>/media/recent/(en el momento actual de la escritura), en realidad no necesita el token de acceso OAuth.

Puedes realizar https://api.instagram.com/v1/users/[USER ID]/media/recent/?client_id=[CLIENT ID]

[ID DE CLIENTE] sería una identificación de cliente válida registrada en la aplicación a través de la gestión de clientes (no relacionada con el usuario). Puede obtener [ID DE USUARIO] del nombre de usuario realizando la solicitud de búsqueda de usuarios GET https://api.instagram.com/v1/users/search?q=[USERNAME]&client_id=[CLIENT ID]

Ersan J Sano
fuente
9
Creo que pueden haber cambiado de opinión nuevamente. Recibo la misma respuesta de error que se muestra en el OP
James
35
Esto solo es válido en aplicaciones creadas antes del 17 de noviembre de 2015, y no será compatible en absoluto después de junio de 2016. Después de eso, necesitará un oauth access_token. instagram.com/developer/changelog
Dax Fohl el
211
Esto es tan estúpido e irritante. ¿Por qué forzarían un token de acceso solo para mostrar imágenes que ya son públicas ? Apenas estoy tratando de enjuagarlos para todos los usuarios del mundo, solo quiero mostrar la última instancia de un cliente sin tener que pasar horas jugando con ella. Gah!
Matt Fletcher
8
@Cabus límites de velocidad, amigo.
Walf
20
@MattFletcher es aún más estúpido ahora, uno debe pasar por la revisión de permisos de la aplicación, y no estoy seguro de si es factible ya que este caso de uso "que muestra el feed del cliente en su propia página web" no es uno de los casos de uso. Duh, estas restricciones apestan.
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>

Puede descargar cualquier feed de fotos de usuario de Instagram en formato JSON usando la ?__a=1dirección de la página de destino como esta . No es necesario obtener una identificación de usuario o registrar una aplicación, sin tokens, sin oAuth.

min_idy las max_idvariables se pueden usar para paginación, aquí hay un ejemplo

YQLes posible que no funcione aquí dentro del iframe cortado, por lo que siempre puede verificarlo manualmente en la Consola YQL

ACTUALIZACIÓN DE ABRIL DE 2018: después de las últimas actualizaciones de instagram, no puede hacer esto en el lado del cliente (javascript) porque los encabezados personalizados para la solicitud firmada no se pueden configurar con javascript debido a CORS Access-Control-Allow-Headersrestricciones. Todavía es posible hacerlo a través de phpo cualquier otro método del lado del servidor con la firma adecuada en función de rhx_gis, csrf_tokeny parámetros de la petición. Puedes leer más sobre esto aquí .

ACTUALIZACIÓN DE ENERO DE 2019: YQL se retiró, así que ¡consulte mi última actualización con Google Image Proxy como CORSproxy para la página de Instagram! Entonces, solo momento negativo: la paginación no está disponible con este método.

PHP solución:

    $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
fuente
14
@ 350D ¿Cómo encontraste esto? No puedo encontrarlo en ninguna parte de su documentación. Solo quiero leer más sobre lo que es posible con este punto final (por ejemplo, imágenes cuadradas versus no cuadradas, si esto tiene planes para terminar en junio, etc.) - ¡Gracias!
Phil Johnston el
8
@Phil Johnston Solo una investigación 😀 Tome esta otra: puede agregar / media /? Size = L junto a la URL de la página de destino de la foto y obtener una foto de resolución COMPLETA.
350D
9
@ user2659694 Finalmente encontré la solución para obtener las siguientes páginas con este método que puede usar / media /? max_id = [MAX_ID]
Reza
3
Para su información, esto parece funcionar solo si usted mismo ha iniciado sesión en una cuenta de Instagram. Intenta hacerlo en modo incógnito en Chrome o similar y verás que la respuesta JSON no contiene elementos. Intenté incorporar esto en un script para obtener la lista de URL en un servidor web y tuve que volver a los viejos métodos de autorización.
Ryan Zink
9
@RyanZink, ¿estabas probando una cuenta privada? funciona bien para mí desconectado o de incógnito en cuentas públicas.
Ryan
41

11.11.2017
Dado que Instagram cambió la forma en que proporcionan estos datos, ninguno de los métodos anteriores funciona en la actualidad. Esta es la nueva forma de obtener los medios del usuario:
OBTENER https://instagram.com/graphql/query/?query_id=17888483320059182&variables={"id":"1951415043","first":20,"after":null}
dónde:
query_id- valor permanente: 17888483320059182 (tenga en cuenta que podría modificarse en el futuro).
id- Identificación del usuario. Puede venir con una lista de usuarios. Para obtener la lista de usuarios, puede utilizar la siguiente solicitud: GET https://www.instagram.com/web/search/topsearch/?context=blended&query=YOUR_QUERY
first- cantidad de elementos para obtener.
after- Identificación del último elemento si desea obtener elementos de esa identificación.

Footniko
fuente
¿Podría decirme de dónde obtener query_id e id del usuario?
Vijaysinh Parmar
2
@VijaysinhParmar como mencioné, query_ides un valor permanente. Eso significa que siempre es 17888483320059182 (al menos a menos que Instagram lo cambie). ID del usuario - es la ID del usuario (editó mi respuesta un poco)
Footniko
1
No recuerdo exactamente, en algún lugar de internet. Pero no tengo ninguna relación con Instagram, así que en caso de que cambie, no podré decirte la nueva :(
Footniko
1
¿Se pregunta cuál es la política de limitación de velocidad de este enfoque?
kkzxak47
1
Si alguien tiene problemas para solicitar esta URL a través de una solicitud CURL, entonces necesita obtener el encabezado de solicitud de cookie (abra la pestaña Redes, después de ejecutar la URL, copie el encabezado de cookie y péguelo en el encabezado de solicitud de curl. Si no hace esto, obtendrá un error de acceso denegado 403).
Anders
39

Pude obtener los medios más recientes de un usuario utilizando la siguiente API sin autenticación (incluida la descripción, los me gusta, el recuento de comentarios).

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

P.ej

https://www.instagram.com/{username}/?__a=1
Miguel
fuente
1
esto también funcionó para mí. pero cuando "is_video = true", no hay URL de video en los datos.
didikee
44
Correcto, solo puede obtener las miniaturas (no el video en sí); desafortunadamente, no encontré ninguna documentación oficial para esto y no tengo idea de si esta API está en desuso o cuánto tiempo va a ser compatible.
Michael
8
A partir del 2018-04-13, esto parece no funcionar más. Quizás debido al último escándalo de datos de Cambridge Analytica en Facebook, están apretando las cosas un montón. ¿Alguna otra sugerencia para obtener datos básicos de usuario sin autenticación?
BakerStreetSystems
2
Sí, hubo un momento en que esta API no funcionaba, pero ahora está de regreso nuevamente
Michael
44
A mí me funcionó, pero solo cuando inicié sesión en Instagram.
zundi
16

A partir de la semana pasada, Instagram deshabilitó las /media/URL, implementé una solución alternativa, que funciona bastante bien por ahora.

Para resolver los problemas de todos en este hilo, escribí esto: https://github.com/whizzzkid/instagram-reverse-proxy

Proporciona todos los datos públicos de instagram utilizando los siguientes puntos finales:

Obtener medios de usuario:

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

Obtenga medios de usuario con recuento de límites:

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

Use JSONP:

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

La API proxy también agrega las URL de la página siguiente y la página anterior a la respuesta, por lo que no es necesario que calcule eso al final.

¡Espero que les guste!

Gracias a @ 350D por ver esto :)

whizzzkid
fuente
1
@rex hasta que cambien la forma en que funcionan las cosas al final, ¡estamos bien! No se molestaron en los últimos 3 años, probablemente no lo harán en los próximos 3.
whizzzkid
3
@whizzzkid Mala suerte, lo cambian. Vi que crees que el punto final del usuario hará las cosas, pero hay límites para las solicitudes de usuarios no conectados. ¿Algunas ideas?
nobilik
1
@nobilik la solución está en su lugar, igpi.ga/whizzzkid/media?count=3 e igpi.ga/graphql/query/?user_id=1606740656&count=3 deben devolver sus datos. Recuerde, los referentes indefinidos están deshabilitados para estas URL.
whizzzkid
1
@whizzzkid - ¡Lo tengo funcionando! Muchas gracias, ¡eres un erudito y un caballero!
James Trickey
1
Recibo un error de "acceso denegado de referencia". Tal vez esto ya no funciona?
khalid13
14

La API de Instagram requiere autenticación de usuario a través de OAuth para acceder al punto final de medios reciente para un usuario. No parece haber otra forma en este momento para obtener todos los medios para un usuario.

Bill Rollins
fuente
44
Esto no tiene sentido, si quiero mostrar mis propios medios en mi propio sitio web, ¿por qué necesito que todos los que quieran verlos tengan una cuenta de Instagram?
ninjasense
55
ninjasense: no creo que sea así como funciona. Creo que su sitio web necesitaría tener un poco de código que consultaría la API de Instagram con sus credenciales proporcionadas para obtener sus medios. Luego mostraría sus medios a cualquier usuario de su sitio. Su sitio sería lo único que necesitaba para autenticarse con Instagram.
Bill Rawlinson
9

Si está buscando una manera de generar un token de acceso para usar en una sola cuenta, puede probar esto -> https://coderwall.com/p/cfgneq .

Necesitaba una forma de usar la API de Instagram para obtener todos los medios más recientes para una cuenta en particular.

Craig Heneveld
fuente
55
Esto es más o menos lo que hice al final: creé una nueva cuenta, hice un token de acceso y almacené ese token en la configuración de mi servidor al lado de la clave API. Sin embargo, esta es una solución pobre para las aplicaciones JS, ya que requiere enviar su token de acceso al usuario (que he visto hacer muchos códigos de ejemplo). Por suerte para mí, puedo hacerlo del lado del servidor.
Peeja
44
@CraigHeneveld ¿Cómo haces para mantener actualizado el hat access_token? ¿No te ha expirado?
Ryan Ore
¿El token caduca en algún momento?
Monitus
Si mi memoria me sirve, la clave solo caduca si cambia su contraseña. Aquí hay otro hilo sobre el asunto -> stackoverflow.com/questions/22753170/…
Craig Heneveld
¿Cómo podemos obtener múltiples fotos de usuario? ¿Cómo podemos pasar varios ID de usuario separados por ","?
Aadil Keshwani
9

Aquí hay una solución de rieles. Es una especie de puerta de atrás, que en realidad es la puerta de entrada.

# 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

El objeto que recuperas varía dependiendo de si es una búsqueda de usuario o una búsqueda de etiqueta. Obtengo los datos de esta manera:

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

Luego obtengo otra página de resultados construyendo una url de la siguiente manera:

  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
fuente
Esta solución me funciona, pero tengo algunos problemas. Después de cargar los datos, mi servidor de rails (usando Rails 5.0.0, Puma 3.6.0 server) se reinicia inexplicablemente ... ¿Alguna solución posible?
Luis Eduardo Rojas Cabrera
8

Gracias al esquema de API siempre cambiante (y horriblemente diseñado) de Instagram, la mayoría de lo anterior ya no funcionará a partir de abril de 2018.

Aquí está la ruta más reciente para acceder a datos de publicaciones individuales si está consultando su API directamente utilizando el https://www.instagram.com/username/?__a=1método.

Suponiendo que sus JSONdatos devueltos es $dataque puede recorrer cada resultado utilizando los siguientes ejemplos de ruta:

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

Las cosas principales en este cambio reciente fueron graphqly edge_owner_to_timeline_media.

Parece que van a acabar con este acceso a la API para los clientes no comerciales en diciembre de 2018, así que aproveche al máximo mientras pueda.

Espero que ayude a alguien;)

especia
fuente
Esto me ayudó, solo quiero mostrar las últimas publicaciones de Instagram para un cliente. ¡Gracias!
weston deboer
1
instagram.com/username/?__a=1 da ahora un error: se denegó el acceso a www.instagram.com No tiene autorización para ver esta página. HTTP ERROR 403 alguna otra idea?
Hese
1
Sí, Instagram ahora ha acabado con esto. "Para mejorar continuamente la privacidad y seguridad de los usuarios de Instagram, estamos acelerando el desuso de la Plataforma API de Instagram, haciendo que los siguientes cambios sean efectivos de inmediato. Entendemos que esto puede afectar su negocio o servicios, y apreciamos su apoyo para mantener nuestra plataforma segura. estas capacidades se desactivarán inmediatamente (previamente fijado para el 31 de julio de, 2018 o el 11 de diciembre de, 2018 desaprobación) ".
especias
Si lo que estoy leyendo es correcto, ya no será posible recuperar imágenes o datos de ninguna cuenta "no comercial". Están matando totalmente la plataforma API. Supongo que es eso entonces ... instagram.com/developer/changelog
spice
1
@james_tookey no será posible amigo. Debido a sus nuevas restricciones de privacidad, ya no podrá consultar o recuperar usuarios / datos de cuentas personales, solo negocios. Básicamente acaban de matar todo el uso de API para cuentas personales.
especias
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;
}
León
fuente
5

Solo quiero agregar a la respuesta @ 350D, ya que fue difícil para mí entender.

Mi lógica en el código es la siguiente:

Cuando llamo a API por primera vez, solo llamo https://www.instagram.com/_vull_ /media/. Cuando recibo respuesta, verifico el valor booleano de more_available. Si es cierto, obtengo la última foto de la matriz, obtengo su identificación y luego llamo a la API de Instagram nuevamente, pero esta vez https://www.instagram.com/_vull_/media/?max_id=1400286183132701451_1642962433.

Lo importante es saber aquí, este Id es el Id de la última imagen en la matriz. Entonces, cuando solicite maxId con la última identificación de la imagen en la matriz, obtendrá las siguientes 20 imágenes, y así sucesivamente.

Espero que esto aclare las cosas.

Vulovic Vukasin
fuente
4

Si omite Oauth, probablemente no sabría qué usuario de instagram son. Dicho esto, hay algunas maneras de obtener imágenes de instagram sin autenticación.

  1. La API de Instagram le permite ver las imágenes más populares de un usuario sin autenticarse. Usando el siguiente punto final: Aquí está el enlace

  2. Instagram proporciona feeds rss para etiquetas en este momento .

  3. Las páginas de usuario de Instagram son públicas, por lo que puede usar PHP con CURL para obtener su página y un analizador DOM para buscar en el html las etiquetas de imagen que desee.

Dorian Damon
fuente
9
Parece anticuado.
Burak Tokak
¿Es posible omitir la autenticación para Instagram?
JAck
3

Un truco más, busca fotos por hashtags:

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

Dónde:

query_hash - valor permanente (creo que su hash de 17888483320059182, se puede cambiar en el futuro)

tag_name - El título habla por sí mismo

first - cantidad de elementos para obtener (no sé por qué, pero este valor no funciona como se esperaba. El número real de fotos devueltas es ligeramente mayor que el valor multiplicado por 4.5 (aproximadamente 110 para el valor 25 y aproximadamente 460 para el valor 100))

after- Identificación del último elemento si desea obtener elementos de esa identificación. El valor de la end_cursorrespuesta de JSON se puede usar aquí.

kara4k
fuente
¿Cómo encuentras esto?
ekntrtmz
2

Se puede utilizar esta API para recuperar información pública del usuario Instagram:
https://api.lityapp.com/instagrams/thebrainscoop?limit=2

Si no se establece el parámetro de límite, los mensajes están limitados a las 12 de manera predeterminada

Este La API se realizó en SpringBoot con HtmlUnit como se puede ver en el código:

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


Es un ejemplo de respuesta:

{
  "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
fuente
¿puedo obtener datos por userid (pk)
SAURABH RATHOD
Lo siento @SAURABHRATHOD Lo intenté pero no he encontrado la manera de hacerlo. Estaría muy contento si alguien resolviera esto. Gracias por el comentario.
Ruan Barroso
2

Realmente necesitaba esta función pero para Wordpress. Encajé y funcionó perfectamente

<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
fuente
1

El siguiente código de nodejs elimina imágenes populares de una página de Instagram. La función 'ScrapeInstagramPage' se encarga del efecto de envejecimiento posterior.

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

Pruébalo aquí

Ejemplo: para una URL dada ' https://www.instagram.com/dress_blouse_designer/ ' se puede llamar a la función

ScrapeInstagramPage ({username : "dress_blouse_designer", debug : false});
Vishnu Kanwar
fuente
Solo puedo ver las primeras 12 publicaciones, ¿cómo puedo obtenerlas todas?
rahul gawale
0

Esto funciona utilizando una simple llamada ajax y recorridos iterativos de imágenes.

        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
fuente
A mí me funcionó, pero solo cuando inicié sesión en Instagram.
zundi
-1

Aquí hay un script php que descarga las imágenes y crea un archivo html con enlaces en las imágenes. Acredite 350D para la versión php, esto es solo elaborado ... Sugeriría poner esto como un trabajo cron y disparar lo que necesite a menudo. Trabajo verificado a partir de mayo de 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);
?>
drooh
fuente