Created
March 27, 2026 05:30
-
-
Save tas33n/d1750e0b07b610c6450fa6fd328cc53e to your computer and use it in GitHub Desktop.
Scrapes an Instagram profile to extract user info based on username
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // author: github.com/tas33n | |
| const fs = require('fs'); | |
| /** | |
| * Scrapes an Instagram profile to extract user info based on username | |
| * @param {string} username - The Instagram username to scrape | |
| * @returns {Promise<Object>} - The structured user data or null if failed | |
| */ | |
| async function scrapeInstagramProfile(username) { | |
| try { | |
| const profileUrl = `https://www.instagram.com/${username}/`; | |
| const cookieString = 'csrftoken=1ljzQha1_HNVy_LXT7qPOd; mid=acYSKgALAAF6WjXyT72IzpuQESsQ; ig_did=3DBBE74E-6E71-4194-AB4F-6CEA1A61E67D; ig_nrcb=1; datr=KBHGaei4RCO-Rl9aKjn4xepQ'; | |
| const csrfTokenMatch = cookieString.match(/csrftoken=([^;]+)/); | |
| const csrfToken = csrfTokenMatch ? csrfTokenMatch[1] : ''; | |
| const profileResponse = await fetch(profileUrl, { | |
| headers: { | |
| 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36', | |
| 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', | |
| 'sec-ch-ua': '"Chromium";v="146", "Not-A.Brand";v="24", "Google Chrome";v="146"', | |
| 'sec-ch-ua-mobile': '?0', | |
| 'sec-ch-ua-platform': '"Windows"', | |
| 'dnt': '1', | |
| 'upgrade-insecure-requests': '1', | |
| 'sec-fetch-site': 'none', | |
| 'sec-fetch-mode': 'navigate', | |
| 'sec-fetch-user': '?1', | |
| 'sec-fetch-dest': 'document', | |
| 'accept-language': 'en-GB,en;q=0.9', | |
| 'priority': 'u=0, i', | |
| 'Cookie': cookieString | |
| } | |
| }); | |
| if (!profileResponse.ok) { | |
| throw new Error(`Failed to fetch profile page. HTTP Status: ${profileResponse.status}`); | |
| } | |
| const html = await profileResponse.text(); | |
| const userIdMatch = html.match(/"user_id":"(\d+)"/); | |
| if (!userIdMatch || !userIdMatch[1]) { | |
| throw new Error("Could not find user_id in the profile page HTML. Instagram might have blocked the request or the DOM structure changed."); | |
| } | |
| const userId = userIdMatch[1]; | |
| const graphqlUrl = 'https://www.instagram.com/graphql/query'; | |
| const variables = { | |
| "enable_integrity_filters": true, | |
| "id": userId, | |
| "render_surface": "PROFILE", | |
| "__relay_internal__pv__PolarisCannesGuardianExperienceEnabledrelayprovider": true, | |
| "__relay_internal__pv__PolarisCASB976ProfileEnabledrelayprovider": false, | |
| "__relay_internal__pv__PolarisWebSchoolsEnabledrelayprovider": false, | |
| "__relay_internal__pv__PolarisRepostsConsumptionEnabledrelayprovider": false | |
| }; | |
| const bodyParams = new URLSearchParams(); | |
| bodyParams.append('variables', JSON.stringify(variables)); | |
| bodyParams.append('doc_id', '34272012165747896'); | |
| const graphqlResponse = await fetch(graphqlUrl, { | |
| method: 'POST', | |
| headers: { | |
| 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36', | |
| 'Accept': '*/*', | |
| 'Content-Type': 'application/x-www-form-urlencoded', | |
| 'x-ig-app-id': '936619743392459', | |
| 'x-fb-friendly-name': 'PolarisProfilePageContentQuery', | |
| 'x-csrftoken': csrfToken, | |
| 'Cookie': cookieString, | |
| 'sec-ch-ua': '"Chromium";v="146", "Not-A.Brand";v="24", "Google Chrome";v="146"', | |
| 'sec-ch-ua-mobile': '?0', | |
| 'sec-ch-ua-platform': '"Windows"', | |
| 'origin': 'https://www.instagram.com', | |
| 'referer': profileUrl, | |
| 'accept-language': 'en-GB,en;q=0.9', | |
| 'priority': 'u=1, i' | |
| }, | |
| body: bodyParams.toString() | |
| }); | |
| if (!graphqlResponse.ok) { | |
| throw new Error(`Failed to fetch GraphQL data. HTTP Status: ${graphqlResponse.status}`); | |
| } | |
| const json = await graphqlResponse.json(); | |
| if (json.status !== 'ok' || !json.data || !json.data.user) { | |
| throw new Error(`Invalid GraphQL response structure or user not found. Status: ${json.status || 'unknown'}`); | |
| } | |
| const user = json.data.user; | |
| const structuredData = { | |
| username: user.username, | |
| userid: user.pk, | |
| thumbnail: user.profile_pic_url, | |
| hd_profile_pic: user.hd_profile_pic_url_info ? user.hd_profile_pic_url_info.url : null, | |
| biography: user.biography, | |
| full_name: user.full_name, | |
| is_verified: user.is_verified, | |
| follower_count: user.follower_count, | |
| following_count: user.following_count, | |
| media_count: user.media_count, | |
| is_private: user.is_private, | |
| is_business: user.is_business, | |
| external_url: user.external_url || null, | |
| category: user.category || null | |
| }; | |
| return structuredData; | |
| } catch (error) { | |
| throw error; | |
| } | |
| } | |
| if (require.main === module) { | |
| const testUsername = '__mithilarahman__'; | |
| scrapeInstagramProfile(testUsername) | |
| .then(data => console.log(JSON.stringify(data, null, 2))) | |
| .catch(err => console.error(err.message)); | |
| } | |
| module.exports = { scrapeInstagramProfile }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment