Posted on September 3, 2015
For some unknown reason, at this time, Instagram does not offer a way to consume the raw images from their API. This means that the max-resolution available over the API is 612×612. This also means that those nifty landscape/portrait images you’ve been making will come through the API as letter-boxed (ick).
So, I got a little carried away this evening and wrote a script to auto-download the high resolution images from my Instagram profile on their website. It’s a little hacky and you’ll have to drop some javascript into your browser console (I’ve only tested Chrome), but works pretty well! Keep in mind… this will only work as long as Instagram’s site works the way it currently does.. So no guarantees this will work (without modifications) in the future.
Just follow the instructions in the below snippet. Let me know if you have any questions!
- 1. Go to your Instagram profile url (e.g. https://instagram.com/jtsternberg/)
- 2. Copy the below snippet to your javascript console (only tested on chrome on OSX/macOS).
!function(t,e,r){var s=t.createElement(e),n=t.getElementsByTagName(e)[0]; s.async=1,s.src=r,n.parentNode.insertBefore(s,n)}(document,"script" ,"https://cdn.rawgit.com/jtsternberg/instascript/master/instascript.js");
window.jQuery = window.jQuery || {}; window.instasScript = window.instasScript || {}; ( function( window, document, $, app, undefined ) { 'use strict'; /** * Instagram Downloader Script * * Instructions: * * 1. Go to your Instagram profile url (e.g. https://instagram.com/jtsternberg/) * 2. Scroll to the bottom, and click the "LOAD MORE" button. This triggers the auto-loading on scroll - http://b.ustin.co/142xL (if you forget, it will prompt you) * 3. Copy this entire thing to your javascript console. (only tested on chrome) * 4. Hit enter and watch your images download. * 5. To stop the process, close the tab or refresh (or hit your escape key). */ /** * instagram image - http://b.ustin.co/1aLvI * * @type {String} */ app.instaImageSelector = '._22yr2'; /** * Full-size instagram image after the modal opens - http://b.ustin.co/18xhe * * @type {String} */ app.modalImageSelector = '._n3cp9._d20no ._jjzlb img'; /** * Full-size instagram video after the modal opens * * @type {String} */ app.modalVideoSelector = '._n3cp9._d20no ._2tomm video'; /** * "Load More" button selector * * @type {String} */ app.loadMoreSelector = '._oidfu'; /** * Closes the modal * * @type {String} */ app.closeButtonSelector = '._3eajp'; /** * Amount of time to allow the image to download. May need to increase this value on a slow connection. * * @type {Number} */ app.downloadBufferTime = 800; /** * Amount of time to allow the freshly-loaded images (after scroll) to load. May need to increase this value on a slow connection. * * @type {Number} */ app.loadMoreBufferTime = 2000; /** * Amount of time to allow the modal to load after triggering it. * * @type {Number} */ app.waitForModalTime = 200; var notified = false; var stop = false; app.dowloaded = []; app.init = function() { var go = function() { alert( "Ok, we're about to begin! Press the 'escape' key to stop the the downloads." ); $ = jQuery; // Listen for escape to stop the import $( document ).on( 'keyup', function( evt ) { if ( 27 === evt.keyCode ) { console.warn( 'STOP dowload script' ); stop = true; } }); app.processNext(); }; if ( ! window.jQuery || ! window.jQuery.fn ) { app.loadjQuery(); setTimeout( go, 1000 ); } else { setTimeout( go, 200 ); } }; app.start = function() { stop = false; app.processNext(); }; app.loadjQuery = function() { var script = document.createElement('script'); script.async = 1; script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js'; var otherscript = document.getElementsByTagName('script')[0]; otherscript.parentNode.insertBefore(script, otherscript); }; app.processNext = function() { if ( stop ) { $( app.closeButtonSelector ).trigger( 'click' ); return alert( "Ok, it's stopped! `instasScript.start()` in your JS console to continue." ); } app.$toClick = $( app.instaImageSelector + ':not(.instadone )' ).first(); if ( ! app.$toClick.length ) { return app.triggerMore(); } app.$toClick.trigger( 'click' ); setTimeout( app.processThis, app.waitForModalTime ); }; app.processThis = function() { var $media = $( app.modalImageSelector ); if ( ! $media.length ) { $media = $( app.modalVideoSelector ); } if ( $media.hasClass( 'instadone' ) ) { return app.processNext(); } if ( ! $media.length ) { return app.processNext(); } var src = $media.attr('src'); var haveIt = $.inArray( src, app.dowloaded ); if ( ! src || -1 !== haveIt ) { if ( ! src ) { console.warn('! src',$media); } if ( -1 !== haveIt ) { console.warn('We have this image!', haveIt, src); } return app.processNext(); } app.$toClick.addClass( 'instadone' ); $media.addClass( 'instadone' ); app.dowloaded.push( app.saveToDisk( src ) ); $( app.closeButtonSelector ).trigger( 'click' ); // Wait a bit to give adequate time to download setTimeout( app.processNext, app.downloadBufferTime ); }; app.triggerMore = function() { if ( $( app.loadMoreSelector ).length ) { return app.needToClickLoadMore(); } var y = $(window).scrollTop(); // your current y position on the page // Jigger the scrolling to trigger the load-more $( 'html, body' ).animate( { scrollTop: y-250 }, 200, 'swing', function() { $( 'html, body' ).animate( { scrollTop: $( document ).height() }, 200 ); }); // Start the processing on the new batch setTimeout( app.processNext, app.loadMoreBufferTime ); }; app.needToClickLoadMore = function() { if ( ! notified ) { notified = true; $( app.closeButtonSelector ).trigger( 'click' ); setTimeout( function() { $( app.loadMoreSelector ).css({ 'box-shadow' : '0px 2px 108px red', 'border-radius' : '100%' }); alert( 'click the "LOAD MORE" button! The download script will continue automatically once "infinite scroll" is triggered.' ); }, 500 ); $( 'html, body' ).animate( { scrollTop: $( document ).height() }, 200 ); } setTimeout( app.triggerMore, app.downloadBufferTime * 2 ); }; app.saveToDisk = function( fileUrl, fileName ) { var hyperlink = document.createElement('a'); hyperlink.href = fileUrl; hyperlink.target = '_blank'; hyperlink.download = fileName || fileUrl; console.log( app.dowloaded.length + ') download', hyperlink.download ); var mouseEvent = new MouseEvent('click', { view: window, bubbles: true, cancelable: true }); hyperlink.dispatchEvent(mouseEvent); (window.URL || window.webkitURL).revokeObjectURL(hyperlink.href); return fileUrl; }; app.init(); } )( window, document, window.jQuery, window.instasScript );
Sadly this line doesn’t appear to work any more: jQuery( instaImageSelector );
Found the issue the class names have changed.
Awesome, can you let me know what the updated class names are so I can update the post?
var instaImageSelector = ‘._jjzlb’;
var modalImageSelector = ‘._n3cp9 _d20no ._jjzlb img’;
var loadMoreSelector = ‘._oidfu’;
var closeButtonSelector = ‘._3eajp’;
Plus a few $’s that need to be jQuery
And I had to load jQuery manually first using this
var jq = document.createElement(‘script’);
jq.src = “https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js”;
document.getElementsByTagName(‘head’)[0].appendChild(jq);
// … give time for script to load, then type.
jQuery.noConflict();
Modal class should be this
var modalImageSelector = ‘._22yr2._e0mru ._jjzlb img’;
Thank you so much for getting back to me! I’ve updated the scrip/post, and the it’s much more robust now, including downloading video files.
Only issue now is it loads them all but doesn’t download anything…
This function seems to take 2 variables but only gets one passed, is that correct?
function save_to_disk( fileUrl, fileName )
dowloaded.push( save_to_disk( src ) );
Unless I still have a class name not quite right, I see the modal opening with the images in, is that also right?
Doesn’t seem to be getting passed this line:
var $img = jQuery( modalImageSelector );
So something still not quite right…
Modal class was wrong, should be this
var modalImageSelector = ‘._22yr2._e0mru ._jjzlb img’;
Its not saving images =/
nvm, it works on chrome, but not on firefox, thank you.
How is it saving on your’s Loki?
I can’t find them anywhere…
Everything works fine, but I cannot seem to find out how to save them to my desktop…
Thanks for all your Hard Work!
Anyone having luck saving these locally?
I can’t find them anywhere…
Everything works fine, but I cannot seem to find out how to save them to my desktop…
Thanks for all your Hard Work!
thanks for this code snipped, i love you for this
❤️
Doesn’t seem to be working anymore, in Chrome. It scrolls all the way down, but doesn’t download anything.