Instagram Posts Scraper
Pricing
from $1.50 / 1,000 results
Instagram Posts Scraper
Stop wasting hours manually analyzing competitors. Automate your growth! Instantly extract top-performing Instagram posts, uncover hidden trends, and turn raw data into your ultimate advantage.
Pricing
from $1.50 / 1,000 results
Rating
0.0
(0)
Developer
Neuro Scraper
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
a month ago
Last modified
Categories
Share
Instagram Post Scraper Instagram Post Scraper is a fast, standalone Python tool that extracts detailed public data from Instagram profiles without requiring a login, cookies, or browser automation. It collects engagement metrics (likes, comments, views), full media content (images, videos, sidecars), captions, hashtags, and music metadata. It's designed for researchers, marketers, and developers who need structured Instagram data exported straight to JSON.
What is Instagram Post Scraper? Instagram Post Scraper is a highly optimized Python script that bypasses the limitations of web-based scraping by interacting directly with Instagram's internal mobile REST API. Because it leverages the same endpoints used by the Instagram web application, it accesses rich data that is often missing or restricted in basic HTML scraping.
Unlike many other solutions, this scraper requires no login, no passwords, and no session cookies. It programmatically fetches a public profile to extract a fresh csrf_token, then seamlessly paginates through the user's feed.
It is completely media-type aware. It intelligently parses Image (type 1), Video (type 2), and Sidecar (carousel, type 8) posts, ensuring that video-specific fields (like view counts and duration) or carousel-specific fields (like child images) are extracted correctly and structured predictably.
What Instagram data is publicly available to scrape? Data Category Publicly Available Restricted behind login Captions, hashtags, mentions Yes — Likes, comments, view/play counts Yes — Video, audio, thumbnail URLs Yes — Owner username, full name, ID Yes — Timestamp, tagged users, co-authors Yes — Private-account posts No Requires following + login Full comment threads No Requires login This scraper only collects data that is publicly visible to logged-out users.
What data can I extract with Instagram Post Scraper? Identity & Ownership Fields Field Name Description id Instagram's internal numeric ID for the post shortCode The short alphanumeric code used in the public URL url The full public URL of the Instagram post inputUrl The profile URL that was scraped to find this post type Media type: Image, Video, or Sidecar productType Instagram's internal product categorization (e.g., clips, feed, carousel_container) ownerUsername The username of the account that posted the content ownerFullName The display name of the posting account ownerId Instagram's internal numeric user ID of the owner coauthorProducers Array of co-authors on the post (includes id, username, fullName) taggedUsers Array of users tagged in the media Engagement & Media Metric Fields Field Name Description likesCount Total number of likes commentsCount Total number of comments videoViewCount Number of views (Video only) videoPlayCount Number of plays / loops (Video only) videoDuration Length of the video in seconds (Video only) dimensionsWidth Original width of the media in pixels dimensionsHeight Original height of the media in pixels timestamp ISO-8601 formatted publishing timestamp Content, Media & Comments Fields Field Name Description caption The full text caption hashtags Array of hashtags extracted from the caption mentions Array of @mentions extracted from the caption alt Accessibility caption (alt text) for images displayUrl Best available thumbnail / display image URL images Array of all available image resolution URLs videoUrl Direct URL to the MP4 video file musicInfo Audio metadata (artist, song name, muting status, original audio flag) childPosts Array of individual media items within a Sidecar/Carousel post isPaidPartnership Boolean indicating if the post is a paid partnership isCommentsDisabled Boolean indicating if comments are turned off Media-Type Specific Behavior The scraper is strictly typed and handles media types differently to prevent data pollution:
Image Posts: videoUrl, videoViewCount, videoPlayCount, videoDuration, and musicInfo are always null. childPosts is an empty array []. Video Posts: Extracts the MP4 link into videoUrl, populates the video metrics, and attempts to extract musicInfo. Cover frames are placed in images. Sidecar (Carousel) Posts: The top-level post acts as a container. video* metrics are null. The childPosts array contains the actual media (which can be a mix of Image and Video types), each with its own specific videoUrl, images, and dimensions. How to configure Instagram Post Scraper Configuration Options You can adjust the scraping parameters by editing the variables at the top of the final_post.py script.
Parameter Type Default Description TARGET_USERNAME string "cristiano" The Instagram username (handle) to scrape. MAX_ITEMS int/None 100 The maximum number of posts to scrape. Set to None to scrape the entire account. OUTPUT_FILE string "insta_post.json" The filename where the JSON data will be saved. REQUEST_DELAY float 1.5 Seconds to pause between page requests to avoid rate limits. Example Configuration python
==============================================================================
USER CONFIGURATION <- edit these
==============================================================================
TARGET_USERNAME = "natgeo" # Instagram username to scrape MAX_ITEMS = 50 # Maximum posts to collect (None = unlimited) OUTPUT_FILE = "natgeo_data.json" REQUEST_DELAY = 2.0 # seconds between pages How to use Instagram Post Scraper Prerequisites: You need Python 3.7+ installed. You also need the requests library. bash
pip install requests Set the Target: Open final_post.py in a text editor and change TARGET_USERNAME to the account you want to scrape. Set the Limit: Change MAX_ITEMS to the number of posts you need (e.g., 500). Run the Script: Execute the file from your terminal. bash
python final_post.py View Output: The scraper will print its progress to the console. Once finished (or manually stopped), your data is safely stored in the insta_post.json (or your configured OUTPUT_FILE) in the same directory. Output Format The scraper saves data incrementally to a JSON file. The root structure contains metadata about the scrape, and a posts array containing the scraped items.
json
{ "username": "cristiano", "total_posts_scraped": 100, "scraped_at": "2026-08-06T15:30:00Z", "posts": [ ... ] } Example Output — Image Post json
{ "inputUrl": "https://www.instagram.com/cristiano/", "id": "3952122654932253942", "type": "Image", "shortCode": "DbYwp2MArz2", "caption": "Cuando te vuelves hacia la luz del sol, las sombras caen detrás de ti. 🌅", "hashtags": [], "mentions": [], "url": "https://www.instagram.com/p/DbYwp2MArz2/", "commentsCount": 219302, "likesCount": 13284301, "timestamp": "2026-08-01T12:00:00.000Z", "ownerFullName": "Cristiano Ronaldo", "ownerUsername": "cristiano", "ownerId": "173560420", "isCommentsDisabled": false, "firstComment": "", "latestComments": [], "productType": "feed", "taggedUsers": [], "coauthorProducers": [], "isPaidPartnership": false, "alt": null, "displayUrl": "https://scontent-sin2-3.cdninstagram.com/v/t51...", "dimensionsHeight": 4096, "dimensionsWidth": 3116, "images": [ "https://scontent-sin2-3.cdninstagram.com/v/t51..." ], "childPosts": [], "videoUrl": null, "videoViewCount": null, "videoPlayCount": null, "videoDuration": null, "musicInfo": null } Example Output — Video Post json
{ "inputUrl": "https://www.instagram.com/cristiano/", "id": "3951593428073548188", "type": "Video", "shortCode": "DbW4UlRF4mc", "caption": "Try my Game Day Blast recipe. Stay sharp. Stay ready. #FuelLikeRonaldo", "hashtags": [ "FuelLikeRonaldo" ], "mentions": [], "url": "https://www.instagram.com/p/DbW4UlRF4mc/", "commentsCount": 19415, "likesCount": 2030859, "timestamp": "2026-07-31T08:30:00.000Z", "ownerFullName": "Herbalife", "ownerUsername": "herbalife", "ownerId": "15890625", "isCommentsDisabled": false, "firstComment": "", "latestComments": [], "productType": "clips", "taggedUsers": [ { "id": "173560420", "username": "cristiano", "fullName": "Cristiano Ronaldo" } ], "coauthorProducers": [ { "id": "173560420", "username": "cristiano", "fullName": "Cristiano Ronaldo" } ], "isPaidPartnership": false, "alt": null, "displayUrl": "https://scontent-sin2-3.cdninstagram.com/v/t51...", "dimensionsHeight": 1920, "dimensionsWidth": 1080, "images": [ "https://scontent-sin2-3.cdninstagram.com/v/t51..." ], "childPosts": [], "videoUrl": "https://scontent-sin2-3.cdninstagram.com/o1/v/t2/f2/m86/AQO2D...", "videoViewCount": 62058800, "videoPlayCount": 62058800, "videoDuration": 19.562000274658203, "musicInfo": { "artist_name": "herbalife", "song_name": "Original audio", "uses_original_audio": true, "should_mute_audio": false, "should_mute_audio_reason": "", "audio_id": "27581399904859106" } } Example Output — Sidecar/Carousel Post json
{ "inputUrl": "https://www.instagram.com/cristiano/", "id": "3956550032798302915", "type": "Sidecar", "shortCode": "DbofUrJAMLD", "caption": "My toys 🚀", "hashtags": [], "mentions": [], "url": "https://www.instagram.com/p/DbofUrJAMLD/", "commentsCount": 219927, "likesCount": 15220275, "timestamp": "2026-08-04T21:05:40.000Z", "ownerFullName": "Cristiano Ronaldo", "ownerUsername": "cristiano", "ownerId": "173560420", "isCommentsDisabled": false, "firstComment": "", "latestComments": [], "productType": "carousel_container", "taggedUsers": [], "coauthorProducers": [], "isPaidPartnership": false, "alt": null, "displayUrl": "https://instagram.fdac2-2.fna.fbcdn.net/v/t51...", "dimensionsHeight": 4096, "dimensionsWidth": 3072, "images": [ "https://instagram.fdac2-2.fna.fbcdn.net/v/t51..." ], "childPosts": [ { "id": "3956548597398537282", "type": "Image", "displayUrl": "https://instagram.fdac2-2.fna.fbcdn.net/v/t51...", "images": [ "https://instagram.fdac2-2.fna.fbcdn.net/v/t51..." ], "dimensionsHeight": 4096, "dimensionsWidth": 3072, "videoUrl": null, "videoDuration": null, "taggedUsers": [], "alt": null }, { "id": "3956548585218255013", "type": "Video", "displayUrl": "https://instagram.fdac2-2.fna.fbcdn.net/v/t51...", "images": [ "https://instagram.fdac2-2.fna.fbcdn.net/v/t51..." ], "dimensionsHeight": 1920, "dimensionsWidth": 1080, "videoUrl": "https://instagram.fdac2-2.fna.fbcdn.net/v/t51...mp4", "videoDuration": 5.4, "taggedUsers": [], "alt": null } ], "videoUrl": null, "videoViewCount": null, "videoPlayCount": null, "videoDuration": null, "musicInfo": null } Field Reference (Complete) Field Name Type Applies To Description inputUrl String All Profile URL scraped id String All Numeric post ID type String All Image, Video, or Sidecar shortCode String All URL identifier caption String All Post text hashtags Array All Tags extracted from caption mentions Array All Mentions extracted from caption url String All Public post URL commentsCount Integer All Number of comments likesCount Integer All Number of likes timestamp String All Publish date (ISO) ownerFullName String All Owner display name ownerUsername String All Owner handle ownerId String All Owner numeric ID isCommentsDisabled Boolean All True if comments disabled firstComment String All Placeholder (always empty string) latestComments Array All Placeholder (always empty array) productType String All Instagram internal type taggedUsers Array All Users tagged in post coauthorProducers Array All Co-authors on the post isPaidPartnership Boolean All True if paid partnership alt String All Image description displayUrl String All Primary thumbnail URL dimensionsHeight Integer All Media height dimensionsWidth Integer All Media width images Array All List of image resolutions childPosts Array Sidecar Media items within carousel videoUrl String Video Direct MP4 link videoViewCount Integer Video Views videoPlayCount Integer Video Plays videoDuration Float Video Length in seconds musicInfo Object Video Artist, song, and mute data How does it work? Instagram Post Scraper does not use Selenium, Playwright, or web scraping libraries like BeautifulSoup. It acts as an API client:
Token Extraction: It makes a standard HTTP GET request to the target profile (https://www.instagram.com/{username}/). It parses the raw HTML using regex to find the csrf_token, which is required for API access. REST API Access: Using the csrf_token and a hardcoded Instagram Web App ID (936619743392459), it queries Instagram's internal mobile REST endpoint: api/v1/feed/user/{username}/username/. This endpoint returns rich, un-minified JSON data intended for mobile apps and modern web clients. Pagination: The API response contains a next_max_id and more_available flag. The script passes next_max_id back to the endpoint in a loop to fetch older posts, batch by batch, until it hits MAX_ITEMS or runs out of posts. Data Normalization: Raw data is passed through _map_item(), which normalizes it into the clean schema above. Incremental Saving: The scraper saves the complete list of collected posts to the JSON file after every single page request. If the script crashes or is interrupted, you do not lose the data collected so far. How does Instagram Post Scraper differ from the official Instagram API? Feature Instagram Graph API Instagram Post Scraper Access scope Only accounts you own/manage Any public account Account requirement Business/Creator account + Facebook Page None Setup time Days (App review & configuration) Minutes (Run script) Media types Basic feed media Images, Reels, Videos, full Carousels Data returned Officially sanctioned metrics Raw internal metrics & media URLs Rate Limits & Error Handling Instagram restricts how rapidly you can request pages without an authenticated session.
REQUEST_DELAY: The script pauses for 1.5 seconds (by default) between pagination requests. Decreasing this heavily risks a temporary IP block (HTTP 429 Too Many Requests). Error Handling: The requests module is configured with raise_for_status(). If a page fails (e.g., due to rate limiting or a network error), the script catches the exception, prints an error message, stops paginating, and saves all data collected up to that point. It will not crash and delete your data. Legal Considerations Scraping publicly available data—data that any logged-out visitor to Instagram can view in their browser—is generally lawful. This scraper only collects public data; it cannot access private accounts or login-gated content. However, because the output includes personal data (usernames, names), regional privacy laws (like GDPR or CCPA) may apply to how you store or process the data after collection. This is factual context, not legal advice.
Frequently Asked Questions Does it require an Instagram account? No. It requires no login, passwords, or session cookies.
How many posts can I scrape? You can scrape up to the entirety of a public user's feed by setting MAX_ITEMS = None. Keep in mind that extremely large accounts may trigger rate limits halfway through.
Does it handle carousel/sidecar posts? Yes. It correctly parses Sidecar posts and places all contained images and videos inside the childPosts array.
What if a username is private? The scraper will fail to fetch the feed because private accounts do not expose timeline data to logged-out users.
Can I change the output filename? Yes, edit the OUTPUT_FILE variable at the top of the script.
What Python version is required? Python 3.7 or newer is recommended.
What happens when Instagram changes its API? If Instagram drastically changes its endpoint structure or requires strict authentication for logged-out users, the scraper may fail. Currently, the api/v1/feed endpoint is highly stable.
Can I scrape multiple users? Out of the box, the script takes a single TARGET_USERNAME. However, you can easily wrap the scrape() function in a Python for loop to process a list of usernames.
Troubleshooting UnicodeEncodeError on Windows: The script contains a built-in fix (io.TextIOWrapper) to force UTF-8 encoding on Windows consoles when printing emojis. HTTP 429 Too Many Requests: Instagram has temporarily rate-limited your IP. Stop the scraper, wait 15-30 minutes, and try again. Consider increasing REQUEST_DELAY. Empty results: If the output is empty, ensure the target account actually has posts and is not set to Private. Could not extract csrf_token: Instagram may be presenting a login wall or captcha to your IP address. This can happen if you scrape too aggressively from a datacenter IP. Try running from a residential connection or VPN. Changelog / Version History v1.0.0 - Initial release. Supports REST API pagination, Image/Video/Sidecar typing, and incremental JSON saving.