├── package.json ├── LICENSE ├── .gitignore ├── . npmignore ├── example.js ├── README.md └── index.js /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "instapro", 3 | "version": "3.0.2", 4 | "description": "A Node.js library that supports the widest range of Instagram endpoints without API keys or authentication.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/preethamvishy/instagram-node.git" 12 | }, 13 | "author": "Preetham Viswanathan", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/preethamvishy/instagram-node/issues" 17 | }, 18 | "homepage": "https://github.com/preethamvishy/instagram-node#readme", 19 | "dependencies": { 20 | "cheerio": "^1.0.0-rc.2", 21 | "es6-promise": "^4.2.4", 22 | "isomorphic-fetch": "^2.2.1", 23 | "request": "^2.88.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Preetham Viswanathan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | 61 | */.DS_Store 62 | .DS_Store -------------------------------------------------------------------------------- /. npmignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | */.DS_Store 3 | .DS_Store 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | 24 | # nyc test coverage 25 | .nyc_output 26 | 27 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 28 | .grunt 29 | 30 | # Bower dependency directory (https://bower.io/) 31 | bower_components 32 | 33 | # node-waf configuration 34 | .lock-wscript 35 | 36 | # Compiled binary addons (http://nodejs.org/api/addons.html) 37 | build/Release 38 | 39 | # Dependency directories 40 | node_modules/ 41 | jspm_packages/ 42 | 43 | # Typescript v1 declaration files 44 | typings/ 45 | 46 | # Optional npm cache directory 47 | .npm 48 | 49 | # Optional eslint cache 50 | .eslintcache 51 | 52 | # Optional REPL history 53 | .node_repl_history 54 | 55 | # Output of 'npm pack' 56 | *.tgz 57 | 58 | # Yarn Integrity file 59 | .yarn-integrity 60 | 61 | # dotenv environment variables file 62 | .env 63 | 64 | -------------------------------------------------------------------------------- /example.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const { 4 | getMediaByCode, 5 | getUserByUsername, 6 | getMediaByLocation, 7 | getMediaByTag, 8 | getMediaLikesByCode, 9 | getMediaCommentsByCode, 10 | generalSearch, 11 | getUserIdFromUsername, 12 | getUserProfilePicture, 13 | getTaggedUsersByCode, 14 | getMediaOwnerByCode 15 | } = require('./index'); 16 | 17 | getUserByUsername('instagram').then((user) => { 18 | console.log(user) 19 | }) 20 | 21 | getUserIdFromUsername('instagram').then((id) => { 22 | console.log(id) 23 | }) 24 | 25 | getMediaByCode('BUu14BdBkO5').then(media => { 26 | console.log(media) 27 | }) 28 | 29 | getMediaOwnerByCode('BUu14BdBkO5').then(media => { 30 | console.log(media) 31 | }) 32 | 33 | getMediaByLocation('292188415').then(({ location }) => { 34 | console.log(location.id) 35 | console.log(location.name) 36 | console.log(location.slug) 37 | }) 38 | 39 | getMediaByTag('abcd').then((media) => { 40 | console.log(media) 41 | }) 42 | 43 | generalSearch('insta').then((results) => { 44 | console.log(results) 45 | }) 46 | 47 | getUserProfilePicture('instagram').then((url) => { 48 | console.log(url) 49 | }) 50 | 51 | getMediaLikesByCode('BUu14BdBkO5').then((media) => { 52 | console.log(media) 53 | }) 54 | 55 | getMediaCommentsByCode('BUu14BdBkO5').then((media) => { 56 | console.log(media) 57 | }) 58 | 59 | getTaggedUsersByCode('BUu14BdBkO5').then((media) => { 60 | console.log(media) 61 | }) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # instapro 🚀 2 | 3 | Get the widest range of Instagram data possible without Instagram API keys or logging in. A Node.js library that supports more endpoints than similar libraries without authentication. 4 | 5 | https://www.npmjs.com/package/instapro 6 | 7 | ![instapro](https://snag.gy/oRpmfX.jpg) 8 | 9 | #### Data available 10 | 11 | - Users' data 12 | - Get User ID from username 13 | - Users' media 14 | - General search 15 | - Media search by tag 16 | - Media search by location 17 | - Media search by shortcode 18 | - Likes and comments for media by shortcode 19 | - Tagged users in media by shortcode 20 | - Media owner data by media shortcode 21 | - Profile picture URL from username 22 | 23 | #### Usage 24 | 25 | Instapro can be installed via npm: `npm install instapro --save` 26 | 27 | `Example.js` provides examples of each supported endpoint. 28 | 29 | ```javascript 30 | 31 | 32 | const { 33 | getMediaByCode, 34 | getUserByUsername, 35 | getMediaByLocation, 36 | getMediaByTag, 37 | getMediaLikesByCode, 38 | getMediaCommentsByCode, 39 | generalSearch, 40 | getUserIdFromUsername, 41 | getUserProfilePicture, 42 | getTaggedUsersByCode, 43 | getMediaOwnerByCode 44 | } = require('./index'); 45 | 46 | getUserByUsername('instagram').then((user) => { 47 | console.log(user) 48 | }) 49 | 50 | getUserIdFromUsername('instagram').then((id) => { 51 | console.log(id) 52 | }) 53 | 54 | getMediaByCode('BUu14BdBkO5').then(media => { 55 | console.log(media) 56 | }) 57 | 58 | getMediaOwnerByCode('BUu14BdBkO5').then(media => { 59 | console.log(media) 60 | }) 61 | 62 | getMediaByLocation('292188415').then(({ location }) => { 63 | console.log(location.id) 64 | console.log(location.name) 65 | console.log(location.slug) 66 | }) 67 | 68 | getMediaByTag('abcd').then((media) => { 69 | console.log(media) 70 | }) 71 | 72 | generalSearch('insta').then((results) => { 73 | console.log(results) 74 | }) 75 | 76 | getUserProfilePicture('instagram').then((url) => { 77 | console.log(url) 78 | }) 79 | 80 | getMediaLikesByCode('BUu14BdBkO5').then((media) => { 81 | console.log(media) 82 | }) 83 | 84 | getMediaCommentsByCode('BUu14BdBkO5').then((media) => { 85 | console.log(media) 86 | }) 87 | 88 | getTaggedUsersByCode('BUu14BdBkO5').then((media) => { 89 | console.log(media) 90 | }) 91 | ``` 92 | 93 | 94 | 95 | ## License 96 | MIT 97 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const fetch = require('isomorphic-fetch') 2 | var request = require('request'); 3 | var cheerio = require('cheerio'); 4 | 5 | var cookie = 'ig_pr=2'; 6 | 7 | exports.getUserByUsername = username => ( 8 | new Promise(function (resolve, reject) { 9 | request(`http://www.instagram.com/` + username, function (err, resp, html) { 10 | if (!err) { 11 | if (resp.statusCode == 200) { 12 | const $ = cheerio.load(html); 13 | $('body').children().each((i, e) => { 14 | eleHTML = $(e).html() 15 | if (eleHTML.indexOf('window._sharedData') > -1) { 16 | resolve(JSON.parse(eleHTML.split('"ProfilePage":[')[1].split(']},"hostname"')[0]).graphql.user); 17 | return false; 18 | } 19 | }) 20 | } else 21 | reject(resp.statusCode) 22 | } else 23 | reject(err); 24 | }) 25 | }) 26 | ); 27 | 28 | exports.getUserIdFromUsername = username => ( 29 | new Promise(function (resolve, reject) { 30 | request(`http://www.instagram.com/` + username, function (err, resp, html) { 31 | if (!err) { 32 | if (resp.statusCode == 200) { 33 | const $ = cheerio.load(html); 34 | var user = {}; 35 | 36 | $('body').children().each((i, e) => { 37 | eleHTML = $(e).html(); 38 | if (eleHTML.indexOf('window._sharedData') > -1) { 39 | resolve(JSON.parse(eleHTML.split('"ProfilePage":[')[1].split(']},"hostname"')[0]).graphql.user.id); 40 | return false; 41 | } 42 | }) 43 | } else 44 | reject(resp.statusCode) 45 | } else 46 | reject(err); 47 | }); 48 | }) 49 | ); 50 | 51 | exports.getMediaByCode = shortcode => ( 52 | fetch(`https://www.instagram.com/p/${shortcode}/?__a=1`, { 53 | headers: { 54 | Cookie: cookie 55 | } 56 | }) 57 | .then(res => { 58 | res.json() 59 | .then(({ 60 | graphql 61 | }) => graphql) 62 | }) 63 | .catch(error => error) 64 | ); 65 | 66 | exports.getMediaCommentsByCode = shortcode => ( 67 | fetch(`https://www.instagram.com/p/${shortcode}/?__a=1`, { 68 | headers: { 69 | Cookie: cookie 70 | } 71 | }) 72 | .then(res => { 73 | res.json() 74 | .then(({ 75 | graphql 76 | }) => graphql.shortcode_media.edge_media_to_comment) 77 | }) 78 | .catch(error => error) 79 | ); 80 | 81 | exports.getTaggedUsersByCode = shortcode => ( 82 | fetch(`https://www.instagram.com/p/${shortcode}/?__a=1`, { 83 | headers: { 84 | Cookie: cookie 85 | } 86 | }) 87 | .then(res => { 88 | res.json() 89 | .then(({ 90 | graphql 91 | }) => graphql.shortcode_media.edge_media_to_tagged_user); 92 | }) 93 | .catch(error => error) 94 | ); 95 | 96 | exports.getMediaLikesByCode = shortcode => ( 97 | fetch(`https://www.instagram.com/p/${shortcode}/?__a=1`, { 98 | headers: { 99 | Cookie: cookie 100 | } 101 | }) 102 | .then(res => { 103 | res.json() 104 | .then(({ 105 | graphql 106 | }) => graphql.shortcode_media.edge_media_preview_like) 107 | }) 108 | .catch(error => error) 109 | ); 110 | 111 | exports.getMediaOwnerByCode = shortcode => ( 112 | fetch(`https://www.instagram.com/p/${shortcode}/?__a=1`, { 113 | headers: { 114 | Cookie: cookie 115 | } 116 | }) 117 | .then(res => { 118 | res.json() 119 | .then(({ 120 | graphql 121 | }) => graphql.shortcode_media.owner) 122 | }) 123 | .catch(error => error) 124 | ); 125 | 126 | exports.getMediaByLocation = (locationId, maxId = '') => ( 127 | fetch(`https://www.instagram.com/explore/locations/${locationId}/?__a=1&max_id=${maxId}`, { 128 | headers: { 129 | Cookie: cookie 130 | } 131 | }) 132 | .then(res => res.json()) 133 | .then(({ 134 | graphql 135 | }) => graphql) 136 | .catch(error => error) 137 | ); 138 | 139 | exports.getMediaByTag = (tag, maxId = '') => ( 140 | fetch(`https://www.instagram.com/explore/tags/${tag}/?__a=1&max_id=${maxId}`, { 141 | headers: { 142 | Cookie: cookie 143 | } 144 | }) 145 | .then(res => res.json()) 146 | .then(({ 147 | graphql 148 | }) => graphql) 149 | .catch(error => error) 150 | ); 151 | 152 | exports.generalSearch = (query) => ( 153 | fetch(`https://www.instagram.com/web/search/topsearch/?query=${query}`, { 154 | headers: { 155 | Cookie: cookie 156 | } 157 | }) 158 | .then(res => res.json()) 159 | .catch(error => error) 160 | ); 161 | 162 | exports.getUserProfilePicture = (username) => ( 163 | new Promise(function (resolve, reject) { 164 | request(`http://www.instagram.com/` + username, function (err, resp, html) { 165 | if (!err) { 166 | if (resp.statusCode == 200) { 167 | const $ = cheerio.load(html); 168 | $('body').children().each((i, e) => { 169 | eleHTML = $(e).html() 170 | if (eleHTML.indexOf('window._sharedData') > -1) { 171 | resolve(JSON.parse(eleHTML.split('"ProfilePage":[')[1].split(']},"hostname"')[0]).graphql.user.profile_pic_url_hd) 172 | return false; 173 | } 174 | }) 175 | } else 176 | reject(resp.statusCode); 177 | } else 178 | reject(err); 179 | }); 180 | }) 181 | ); 182 | --------------------------------------------------------------------------------