如何在不验证用户身份的情况下从Instagram获取用户的媒体?

Pee*_*eja 169 instagram instagram-api

我试图将用户最近的Instagram媒体放在侧边栏上.我正在尝试使用Instagram API来获取媒体.

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

文档说到GET https://api.instagram.com/v1/users/<user-id>/media/recent/,但它说要传递OAuth访问令牌.访问令牌代表代表用户行事的授权.我不希望用户登录Instagram以在侧栏上看到这一点.他们甚至不需要拥有Instagram帐户.

例如,我可以在没有登录Instagram并查看照片的情况下访问http://instagram.com/thebrainscoop.我想通过API来做到这一点.

在Instagram API中,非用户身份验证的请求通过client_id而不是access_token.但是,如果我尝试这样做,我得到:

{
  "meta":{
    "error_type":"OAuthParameterException",
    "code":400,
    "error_message":"\"access_token\" URL parameter missing. This OAuth request requires an \"access_token\" URL parameter."
  }
}
Run Code Online (Sandbox Code Playgroud)

那么,这不可能吗?没有要求用户首先通过OAuth登录Instagram帐户,是否无法获取用户的最新(公共)媒体?

350*_*50D 323

var name = "smena8m";
$.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) {
          var node = edge.node;
          $('body').append(
              $('<a/>', {
              href: 'https://instagr.am/p/'+node.shortcode,
              target: '_blank'
          }).css({
              backgroundImage: 'url(' + node.thumbnail_src + ')'
          }));
      });
    }
});
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

您可以使用下载JSON格式的任何用户的Instagram照片进?__a=1旁边的着陆页网址这样.无需获取用户ID或注册应用程序,无需令牌,无需oAuth.

min_idmax_id变量可用于分页,这是一个例子

YQL可能无法在剪切的iframe内部工作,因此您始终可以在YQL控制台中手动检查它

2018年4月更新:在最新的Instagram更新后,您无法在客户端(javascript)执行此操作,因为由于CORS Access-Control-Allow-Headers限制,无法使用javascript设置签名请求的自定义标头.它仍然可以通过做这个php或任何其他服务器端方法与基于适当的签名rhx_gis,csrf_token和请求参数.你可以在这里阅读更多相关信息.

2019年1月更新:YQL已退役,因此,请使用Google Image Proxy检查我的最新更新作为CORSInstagram页面的代理!然后只有负面时刻 - 这种方法无法获得分页.

PHP 解:

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

  • @ 350D你是怎么发现这个的?我在他们的文档中找不到它.我只是想了解更多关于这个端点的可能性(EG方形图像与非方形,是否有计划在6月结束等) - 谢谢! (14认同)
  • @ user2659694我终于找到了使用这种方法获取下一页的解决方案你可以使用/ media /?max_id = [MAX_ID] (9认同)
  • @RyanZink你在尝试私人账户吗?它适用于我登出或隐藏在公共帐户上. (9认同)
  • @Phil Johnston只是一项研究另外一个 - 您可以在照片着陆页网址旁边添加/ media /?size = L并获得全分辨率照片. (8认同)
  • 仅供参考,如果您自己登录Instagram帐户,这似乎只有效.尝试在Chrome或类似设备的隐身版中执行此操作,您会看到JSON响应中不包含任何项目.我试图将其合并到一个脚本中以获取Web服务器上的URL列表,并且必须返回旧的授权方法. (3认同)
  • @RyanZink对我来说不对 - 我甚至用Tor解开它 (2认同)
  • @bCliks此处没有选项,没有可用于这些端点的JSONP或跨域 (2认同)
  • @Hadnazzar你错过了跨域限制.没有cors,没有jsonp,没有可用于这些端点的跨域.服务器只使用. (2认同)
  • 哦,天哪......为什么这不是Instagram的API文档中的第一件事? (2认同)

Ers*_*ano 122

这已经很晚了,但是如果有人帮助我,就像我在Instagram的文档中没有看到它一样.

要执行GET https://api.instagram.com/v1/users/<user-id>/media/recent/(在写入的当前时间),您实际上不需要OAuth访问令牌.

你可以表演 https://api.instagram.com/v1/users/[USER ID]/media/recent/?client_id=[CLIENT ID]

[CLIENT ID]将是通过管理客户端在应用程序中注册的有效客户端ID(与用户无关).您可以通过执行GET用户搜索请求从用户名获取[USER ID]: https://api.instagram.com/v1/users/search?q=[USERNAME]&client_id=[CLIENT ID]

  • 这是如此愚蠢和恼人.为什么他们会强制访问令牌只是为了显示*已经公开*的图像?我几乎不想为世界上的每个用户冲洗它们,我只是想展示一个客户端的最新版本而不必花费数小时搞乱它.尔加! (201认同)
  • 这仅适用于2015年11月17日之前创建的应用,2016年6月之后将不再受支持.之后您将需要oauth access_token.https://instagram.com/developer/changelog/ (35认同)
  • @MattFletcher现在更加愚蠢,必须通过应用程序权限审核,并且不确定它是否可行,因为此用例"在自己的网页中显示客户自己的提要"不是用例之一.呃,这些限制很糟糕. (19认同)
  • 我想他们可能会再次改变主意.我得到了与OP中显示的相同的错误响应 (9认同)
  • @Cabus速率限制,交配. (8认同)
  • 这不再对我有用. (4认同)

Foo*_*iko 37

11.11.2017
由于Instagram改变了他们提供这些数据的方式,现在上述方法都没有奏效.以下是获取用户媒体的新方法:
GET https://instagram.com/graphql/query/?query_id=17888483320059182&variables={"id":"1951415043","first":20,"after":null}
其中:
query_id- 永久值:17888483320059182(注意将来可能会更改).
id - 用户的ID.它可能带有用户列表.要获取用户列表,您可以使用以下请求:GET https://www.instagram.com/web/search/topsearch/?context=blended&query=YOUR_QUERY
first- 要获取的项目数量.
after - 如果您想从该ID获取项目,则为最后一项的ID.

  • @VijaysinhParmar正如我所提到的,`query_id`是永久值.这意味着它总是**17888483320059182**(至少除非Instagram改变它).用户的id - 是用户的id(编辑了我的答案) (2认同)
  • 想知道这种方法的速率限制策略是什么? (2认同)

Mic*_*ael 30

我能够在没有身份验证的情况下使用以下API获取用户的最新媒体(包括描述,喜欢,评论计数).

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

例如

https://www.instagram.com/{username}/?__a=1
Run Code Online (Sandbox Code Playgroud)

  • 截至2018-04-13,这似乎不再适用.也许是因为Facebook最新的剑桥Analytica数据丑闻,他们收紧了一吨.没有身份验证获取基本用户数据的任何其他建议? (8认同)
  • 是的,你只能获得缩略图(而不是视频本身) - 遗憾的是,我没有找到任何官方文档,我不知道这个API是否已被弃用或者支持多长时间. (4认同)
  • 它适用于我,但只有当我登录Instagram时. (4认同)
  • 是的,曾经有一段时间这个API无效 - 但现在它又回来了 (2认同)
  • 截至2019年1月,@ zundi的评论是正确的 (2认同)

whi*_*kid 16

截至上周,Instagram禁用了/media/网址,我实施了一个解决方法,现在效果很好.

为了解决这个问题中每个人的问题,我写了这个:https://github.com/whizzzkid/instagram-reverse-proxy

它使用以下端点提供所有instagram的公共数据:

获取用户媒体:

https://igapi.ga/<username>/media
e.g.: https://igapi.ga/whizzzkid/media 
Run Code Online (Sandbox Code Playgroud)

获取具有限制计数的用户媒体:

https://igapi.ga/<username>/media?count=N // 1 < N < 20
e.g.: https://igapi.ga/whizzzkid/media?count=5
Run Code Online (Sandbox Code Playgroud)

使用JSONP:

https://igapi.ga/<username>/media?callback=foo
e.g.: https://igapi.ga/whizzzkid/media?callback=bar
Run Code Online (Sandbox Code Playgroud)

代理API还会将下一页和上一页网址附加到响应中,因此您无需在最后计算.

希望你们喜欢!

感谢@ 350D发现这个:)

  • @whizzzkid运气不好,他们改变了.我看到你认为用户端点会做这些事情,但对未登录用户的请求有限制.有任何想法吗? (3认同)

小智 14

Instagram API要求通过OAuth进行用户身份验证,以便为用户访问最近的媒体端点.现在似乎没有任何其他方式来为用户获取所有媒体.

  • ninjasense - 我不认为这是如何运作的.我认为您的网站需要有一些代码,可以使用您提供的oauth凭据查询Instagram API以提取您的媒体.然后,您可以向您网站的任何用户展示您的媒体.您的网站将是唯一需要通过Instagram进行身份验证的网站. (5认同)
  • 这没有任何意义,如果我想在自己的网站上显示我自己的媒体,为什么我需要每个想要看到它的人拥有一个Instagram帐户? (4认同)
  • 这很奇怪.但它似乎是正确的.该死的. (2认同)

小智 9

如果您正在寻找一种生成访问令牌以在单个帐户上使用的方法,您可以尝试这一点 - > https://coderwall.com/p/cfgneq.

我需要一种方法来使用instagram api来获取特定帐户的所有最新媒体.

  • 这或多或少是我最终做的:创建一个新帐户,为它创建一个访问令牌,并将该令牌存储在API密钥旁边的服务器配置中.但是,对于JS应用程序来说,这是一个糟糕的解决方案,因为它需要将您的访问令牌发送给用户(我已经看过很多示例代码).幸运的是,我可以在服务器端做到这一点. (5认同)
  • @CraigHeneveld你如何保持帽子access_token是最新的?它已经过期了吗? (4认同)

Ben*_*man 9

这是一个rails解决方案.它是一种后门,实际上是前门.

# 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
Run Code Online (Sandbox Code Playgroud)

您获得的对象取决于它是用户搜索还是标签搜索.我得到这样的数据:

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
Run Code Online (Sandbox Code Playgroud)

然后,我通过以下方式构建URL来获取另一页结果:

  uri = 'https://www.instagram.com/explore/tags/' + query_string.to_s\
    + '?&max_id=' + max_id.to_s
  uri = 'https://www.instagram.com/' + query_string.to_s + '?&max_id='\
    + max_id.to_s if type === 'user'
Run Code Online (Sandbox Code Playgroud)


spi*_*ice 8

感谢Instagram不断变化(以及可怕的设计)API架构,上述大部分内容将不再适用于2018年4月.

如果您使用该https://www.instagram.com/username/?__a=1方法直接查询其API,则这是访问单个帖子数据的最新路径.

假设您返回的JSON数据是,$data您可以使用以下路径示例循环遍历每个结果:

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

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

最近这一变化的主要内容是graphqledge_owner_to_timeline_media.

看起来他们将在DEC 2018中为非"业务"客户终止这种API访问,因此尽可能充分利用它.

希望它可以帮助某人;)

  • https://www.instagram.com/username/?__a=1 现在给出错误:访问 www.instagram.com 被拒绝您无权查看此页面。HTTP ERROR 403 还有其他想法吗? (2认同)
  • 是的,Instagram 现在已经取消了这个功能。“为了不断提高 Instagram 用户的隐私和安全性,我们正在加速弃用 Instagram API 平台,使以下更改立即生效。我们了解这可能会影响您的业务或服务,我们感谢您在确保我们平台安全方面的支持。这些功能将立即被禁用(之前设定为2018年7月31日或2018年12月11日弃用)。” (2认同)

小智 6

如果您想在没有 clientID 和访问令牌的情况下搜索用户:

1:如果你想搜索所有与你的名字与你的搜索词相似的用户:

将 SeachName 替换为您要搜索的文本:

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

2:如果你想搜索完全相同的名称用户:

将 UserName 替换为您想要的搜索名称:

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


Vul*_*sin 5

只想添加到@ 350D答案,因为我很难理解.

我的代码逻辑是下一个:

第一次调用API时,我只是在调用https://www.instagram.com/_vull_ /media/.当我收到回复时,我检查了布尔值more_available.如果是真的,我从数组中获取最后一张照片,获取其ID,然后再次调用Instagram API,但这一次 https://www.instagram.com/_vull_/media/?max_id=1400286183132701451_1642962433.

重要的是要知道这个,这个Id是数组中最后一张图片的Id.因此,当要求maxId使用数组中图片的最后一个id时,您将获得接下来的20张图片,依此类推.

希望这能澄清事情.

  • 从今天起不工作,Instagram改变了它. (4认同)

kar*_*a4k 5

还有一个技巧,通过标签搜索照片:

GET https://www.instagram.com/graphql/query/?query_hash=3e7706b09c6184d5eafd8b032dbcf487&variables={"tag_name":"nature","first":25,"after":""}
Run Code Online (Sandbox Code Playgroud)

在哪里:

query_hash - 永久值(我相信它的哈希值为 17888483320059182,将来可以更改)

tag_name - 标题不言自明

first - 要获取的项目数量(不知道为什么,但这个值没有按预期工作。实际返回的照片数量略大于乘以4.5的值(值25约为110,值25约为460)值 100))

after- 如果您想从该 id 中获取项目,则为最后一个项目的 id。end_cursor可以在此处使用来自 JSON 响应的值。


Leo*_*Leo 5

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

    });

});
Run Code Online (Sandbox Code Playgroud)

HTML:

<ul class="instagram">
</ul>
Run Code Online (Sandbox Code Playgroud)

CSS:

ul.instagram {
    list-style: none;
}

ul.instagram li {
  float: left;
}

ul.instagram li img {
    height: 100px;
}
Run Code Online (Sandbox Code Playgroud)