如何在不authentication用户的情况下从Instagram获取用户媒体?

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

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

该文件说GET GET https://api.instagram.com/v1/users/<user-id>/media/recent/ ,但它说要传递OAuth访问令牌。 访问令牌表示授权代表用户行事。 我不希望用户login到Instagram上看到这个侧边栏。 他们甚至不需要有一个Instagram帐户。

例如,我可以访问http://instagram.com/thebrainscoop,而不必loginInstagram并查看照片。 我想通过API来做到这一点。

在Instagram API中,非用户authentication的请求传递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." } } 

那么,这是不可能的? 在没有要求用户通过OAuth首先loginInstagram帐户的情况下,没有办法获取用户的最新(公共)媒体?

现在已经很晚了,但是如果能够帮助某个人的话,这是值得的,因为我没有在Instagram的文档中看到它。

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

您可以执行https://api.instagram.com/v1/users/[USER ID]/media/recent/?client_id=[CLIENT ID]

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

 var name = "smena8m", items; $.getJSON("https://query.yahooapis.com/v1/public/yql?callback=?", { q: "select * from json where url='https://www.instagram.com/" + name + "/?__a=1'", format: "json" }, function(data) { console.log(data); if (data.query.results) { items = data.query.results.json.user.media.nodes; $.each(items, function(n, item) { $('body').append( $('<a/>', { href: 'https://www.instagram.com/p/'+item.code, target: '_blank' }).css({ backgroundImage: 'url(' + item.thumbnail_src + ')' })); }); } }); 
 html, body { font-size: 0; line-height: 0; } a { display: inline-block; width: 25%; height: 0; padding-bottom: 25%; background: #eee 50% 50% no-repeat; background-size: cover; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

截至上周,Instagram禁用/media/url,我实施了一个解决方法,目前运行良好。

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

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

获取用户媒体:

 https://igapi.ga/<username>/media eg: https://igapi.ga/whizzzkid/media 

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

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

使用JSONP:

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

代理API还会将下一页和上一页url附加到响应中,因此您不需要在结尾处计算该url。

希望你们喜欢!

感谢@ 350D的发现这:)

Instagram API要求通过OAuth进行用户身份validation才能访问用户的最近媒体端点。 现在似乎没有任何其他方式获取用户的所有媒体。

如果您正在寻找一种方法来生成访问令牌以便在单个帐户上使用,则可以尝试此操作 – > https://coderwall.com/p/cfgneq

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

这是一个导轨解决scheme。 这是一种后门,实际上是前门。

 # 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 

您取回的对象取决于它是否是用户search或标签search。 我得到这样的数据:

 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 

然后,我通过以下方式构build一个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' 

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

我的代码逻辑是:

第一次调用API时,我只打电话https://www.instagram.com/_vull_ /media/ 。 当我收到回应时,我检查more_available布尔值。 如果它是真的,我从数组中获得最后一张照片,得到它的id,然后再次调用Instagram的API,但这次https://www.instagram.com/_vull_/media/?max_id=1400286183132701451_1642962433

这里要知道的重要的事情是,这个ID是arrays中最后一张照片的ID。 所以当用数组中的图片的最后一个id来请求maxId时,会得到接下来的20张图片,依此类推。

希望这个澄清的事情。

二〇一七年十一月一十一日
由于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 – 得到的项目数量。
如果你想从这个ID获取项目的最后一个项目的ID后。

如果绕过Oauth,你可能不知道他们是哪个instagram用户。 这就是说,有几种方法可以在没有身份validation的情况下获取instagram图片。

  1. Instagram的API可以让您无需authentication即可查看用户最stream行的图片。 使用以下端点: 这里是链接

  2. Instagram提供标签的RSS提要。

  3. Instagram的用户页面是公开的,所以你可以使用PHP和CURL来获取他们的页面和一个DOMparsing器来searchHTML的图像标签。

下面的nodejs代码从Instagram页面中删除stream行的图片。 “ScrapeInstagramPage”function负责后期老化效果。

 var request = require('parse5'); var request = require('request'); var rp = require('request-promise'); var $ = require('cheerio'); // Basically jQuery for node.js const jsdom = require("jsdom"); const { JSDOM } = jsdom; function ScrapeInstagramPage (args) { dout("ScrapeInstagramPage for username -> " + args.username); var query_url = 'https://www.instagram.com/' + args.username + '/'; var cookieString = ''; var options = { url: query_url, method: 'GET', headers: { 'x-requested-with' : 'XMLHttpRequest', 'accept-language' : 'en-US,en;q=0.8,pt;q=0.6,hi;q=0.4', 'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36', 'referer' : 'https://www.instagram.com/dress_blouse_designer/', 'Cookie' : cookieString, 'Accept' : '*/*', 'Connection' : 'keep-alive', 'authority' : 'www.instagram.com' } }; function dout (msg) { if (args.debug) { console.log(msg); } } function autoParse(body, response, resolveWithFullResponse) { // FIXME: The content type string could contain additional values like the charset. // Consider using the `content-type` library for a robust comparison. if (response.headers['content-type'] === 'application/json') { return JSON.parse(body); } else if (response.headers['content-type'] === 'text/html') { return $.load(body); } else { return body; } } options.transform = autoParse; rp(options) .then(function (autoParsedBody) { if (args.debug) { console.log("Responce of 'Get first user page': "); console.log(autoParsedBody); console.log("Creating JSDOM from above Responce..."); } const dom = new JSDOM(autoParsedBody.html(), { runScripts: "dangerously" }); if (args.debug) console.log(dom.window._sharedData); // full data doc form instagram for a page var user = dom.window._sharedData.entry_data.ProfilePage[0].user; if (args.debug) { console.log(user); // page user console.log(user.id); // user ID console.log(user.full_name); // user full_name console.log(user.username); // user username console.log(user.followed_by.count); // user followed_by console.log(user.profile_pic_url_hd); // user profile pic console.log(autoParsedBody.html()); } if (user.is_private) { dout ("User account is PRIVATE"); } else { dout ("User account is public"); GetPostsFromUser(user.id, 5000, undefined); } }) .catch(function (err) { console.log( "ERROR: " + err ); }); var pop_posts = []; function GetPostsFromUser (user_id, first, end_cursor) { var end_cursor_str = ""; if (end_cursor != undefined) { end_cursor_str = '&after=' + end_cursor; } options.url = 'https://www.instagram.com/graphql/query/?query_id=17880160963012870&id=' + user_id + '&first=' + first + end_cursor_str; rp(options) .then(function (autoParsedBody) { if (autoParsedBody.status === "ok") { if (args.debug) console.log(autoParsedBody.data); var posts = autoParsedBody.data.user.edge_owner_to_timeline_media; // POSTS processing if (posts.edges.length > 0) { //console.log(posts.edges); pop_posts = pop_posts.concat (posts.edges.map(function(e) { var d = new Date(); var now_seconds = d.getTime() / 1000; var seconds_since_post = now_seconds - e.node.taken_at_timestamp; //console.log("seconds_since_post: " + seconds_since_post); var ageing = 10; // valuses (1-10]; big value means no ageing var days_since_post = Math.floor(seconds_since_post/(24*60*60)); var df = (Math.log(ageing+days_since_post) / (Math.log(ageing))); var likes_per_day = (e.node.edge_liked_by.count / df); // console.log("likes: " + e.node.edge_liked_by.count); //console.log("df: " + df); //console.log("likes_per_day: " + likes_per_day); //return (likes_per_day > 10 * 1000); var obj = {}; obj.url = e.node.display_url; obj.likes_per_day = likes_per_day; obj.days_since_post = days_since_post; obj.total_likes = e.node.edge_liked_by.count; return obj; } )); pop_posts.sort(function (b,a) { if (a.likes_per_day < b.likes_per_day) return -1; if (a.likes_per_day > b.likes_per_day) return 1; return 0; }); //console.log(pop_posts); pop_posts.forEach(function (obj) { console.log(obj.url); }); } if (posts.page_info.has_next_page) { GetPostsFromUser(user_id, first, posts.page_info.end_cursor); } } else { console.log( "ERROR: Posts AJAX call not returned good..." ); } }) .catch(function (err) { console.log( "ERROR: " + err ); }); } } ScrapeInstagramPage ({username : "dress_blouse_designer", debug : false}); 

在这里尝试

例如:对于给定的URL“ https://www.instagram.com/dress_blouse_designer/ ”,可以调用函数

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