Instagram Reels Scraper
Pricing
$4.99/month + usage
Instagram Reels Scraper
Unlock unlimited Instagram Reels instantly! Extract watermark-free MP4s, viral audio data, and hidden metrics like views and love count. 100% login-free. Powered by built-in residential proxies for lightning-fast, ban-free scraping.
Pricing
$4.99/month + usage
Rating
0.0
(0)
Developer
Neuro Scraper
Maintained by CommunityActor stats
1
Bookmarked
69
Total users
3
Monthly active users
15 days ago
Last modified
Categories
Share
The Instagram Reels Scraper is a highly efficient, stealthy, and scalable Apify Actor designed to extract comprehensive data from public Instagram Reels. It returns detailed media URLs, engagement metrics (likes, views, plays, shares, comments), audio/music metadata, and full captions directly from any user's profile. Designed for researchers, marketers, and developers, it bypasses the need for official Instagram API limits by leveraging Instagram's internal GraphQL endpoints with Apify's Residential Proxies.
What is Instagram Reels Scraper?
The Instagram Reels Scraper is your ultimate solution for extracting high-value video content and engagement metrics from any public Instagram profile. Say goodbye to complex setups and unreliable browser automation—this tool is built for pure speed and reliability. Whether you're tracking viral audio trends, monitoring competitor performance, or feeding video transcripts into machine learning models, you'll get lightning-fast, highly-structured data delivered right to you.
🌟 Why choose this scraper?
- Zero Login Required: Access thousands of Reels from public profiles effortlessly. No need to risk your personal Instagram account or navigate complex developer approvals.
- Unstoppable Performance: Powered by enterprise-grade residential proxies seamlessly integrated behind the scenes, you can extract data at scale without worrying about IP bans or rate limits.
- Deep Insights: Capture everything that matters—from pristine, watermark-free video URLs and original audio tracks to deep engagement metrics like views, plays, shares, and top comments.
It's the perfect, plug-and-play powerhouse for marketers, researchers, and data scientists who need pristine data fast.
What Instagram data is publicly available to scrape?
| Data Category | Publicly Available |
|---|---|
| Public User Profile Info | Yes (Username, Full Name, User ID) |
| Reel Video & Audio URLs | Yes (Without watermarks) |
| Engagement Metrics | Yes (Likes, Views, Plays, Comments Count, Shares) |
| Captions, Mentions & Hashtags | Yes |
| Latest Comments | Yes (Top threaded comments available on the node) |
| Music & Audio Metadata | Yes (Artist, Song, Mute reasons, Original Audio flag) |
| Private Account Content | No (Unless valid cookieHeader with access is provided) |
| Historical Story Data | No |
What data can I extract with Instagram Reels Scraper?
Identity & Ownership Fields
| Field Name | Description |
|---|---|
ownerId | The unique numeric ID of the account that posted the Reel. |
ownerUsername | The handle/username of the creator (e.g., cristiano). |
ownerFullName | The display name of the creator. |
Engagement & Media Metric Fields
| Field Name | Description |
|---|---|
likesCount | Total number of likes the Reel has received. |
commentsCount | Total number of comments on the Reel. |
videoViewCount | Total number of views. |
videoPlayCount | Total number of plays (often identical to views). |
sharesCount | Total number of times the Reel was shared/reshared. |
isPinned | Boolean indicating if the Reel is pinned to the top of the profile. |
isCommentsDisabled | Boolean indicating if the creator disabled comments. |
Content, Media & Comments Fields
| Field Name | Description |
|---|---|
id | The unique numeric ID of the Reel media. |
shortCode | The short alphanumeric code used in the URL (e.g., p/{shortCode}). |
url | The full public URL to the post. |
inputUrl | The target URL provided as input to the scraper. |
type | Media type (Hardcoded to "Video"). |
productType | Usually "clips", "reels", or "igtv". |
caption | The full text caption of the Reel. |
alt | Accessibility caption/alt-text, if available. |
hashtags | Array of hashtags extracted from the caption. |
mentions | Array of @mentions extracted from the caption. |
timestamp | ISO-8601 formatted timestamp of when the Reel was posted. |
dimensionsHeight | The original height of the video in pixels. |
dimensionsWidth | The original width of the video in pixels. |
images | Array of thumbnail/cover image URLs at various resolutions. |
displayUrl | The highest resolution cover image URL. |
videoUrl | The direct MP4 video URL. |
videoDuration | Length of the video in seconds. |
audioUrl | Direct URL to the progressive download of the audio track. |
musicInfo | Object containing artist_name, song_name, uses_original_audio, should_mute_audio, should_mute_audio_reason, and audio_id. |
transcript | Auto-generated clips transcript, if available. |
latestComments | Array of objects representing the most recent comments (includes id, text, ownerUsername, timestamp, likesCount, etc.). |
firstComment | The text of the most recent comment. |
childPosts | Array for sidecar children (Always empty [] for this Reel scraper). |
downloadedVideo | Placeholder string (always empty ""). |
Media-Type Specific Behavior
The scraper is strictly designed to filter and extract Video/Reels.
- Video/Reels: Fully parsed.
videoUrl,audioUrl,musicInfo, andvideoDurationwill be populated. Thetypeis always set to"Video". - Image Posts: Ignored. The scraper's
_is_reelfunction actively filters out standard GraphImages. - Sidecar/Carousel Posts: Ignored unless the sidecar contains a video child node (
is_video). If it does contain a video, the parent node is parsed as a Video. However, because the GraphQL timeline endpoint aggregates the parent node, the nestedchildPostsarray will remain empty ([]), and the media URLs will reflect the cover of the sidecar.
How to configure Instagram Reels Scraper
Configuration Options
| Parameter | Type | Default | Description |
|---|---|---|---|
usernames | Array of Strings | [] | List of Instagram usernames or profile URLs to scrape. |
resultsLimit | Integer | 10 | Maximum number of Reels to extract per username. Set to 0 for unlimited. |
cookieHeader | String | "" | Optional raw Cookie string from an authenticated browser session to bypass strict blocks or scrape private profiles. |
requestDelay | Float | 1.5 | Delay in seconds between paginated GraphQL requests to avoid rate limits. |
(Note: Apify Residential Proxies are hardcoded directly into the script to ensure maximum success rates. No proxy configuration is required from the user in the UI.)
Example Configuration
{"usernames": ["cristiano","https://www.instagram.com/nasa/"],"resultsLimit": 50,"requestDelay": 2.0,"cookieHeader": "sessionid=123456789%3Aabcdefg..."}
How to use Instagram Reels Scraper
- Prerequisites: Ensure you have Python 3.9+ installed and the required libraries:
requestsandapify. - Setup Input: Pass your target profiles into the
usernamesarray via the Apify Actor input UI or a local JSON input file. - Set Max Items: Adjust
resultsLimitto restrict how many videos you pull per profile (e.g.,100). Use0to scrape the entire account history. - Run the Script: Run the Actor on the Apify Platform, or locally via the Apify CLI (
apify run). - Output Collection: The scraped data will be dynamically pushed to the default Apify Dataset, where it can be exported to JSON, CSV, Excel, or accessed via API.
Output Format
The output is highly structured JSON. Each item in the dataset represents a single Reel.
Example Output — Image Post
(Note: Because this scraper explicitly filters out standard images via _is_reel, standard image posts will not be scraped. If they were hypothetically captured, videoUrl, audioUrl, and musicInfo would be null or empty, while dimensions and displayUrl would be populated.)
Example Output — Video Post
{"id": "3123456789012345678","type": "Video","shortCode": "Cvxyz123abc","caption": "Amazing goal! ⚽🔥 #football #legend @juventus","hashtags": ["football", "legend"],"mentions": ["juventus"],"url": "https://www.instagram.com/p/Cvxyz123abc/","commentsCount": 14500,"dimensionsHeight": 1920,"dimensionsWidth": 1080,"images": ["https://scontent-iad3-1.cdninstagram.com/v/t51.2885-15/312345678_123_n.jpg?..."],"videoUrl": "https://scontent-iad3-1.cdninstagram.com/v/t50.2886-16/312345678_123_n.mp4?...","likesCount": 1250000,"timestamp": "2023-08-15T12:30:00.000Z","ownerFullName": "Cristiano Ronaldo","ownerUsername": "cristiano","ownerId": "173560420","isPinned": false,"productType": "clips","videoDuration": 15.4,"inputUrl": "https://www.instagram.com/cristiano/","firstComment": "GOAT! 🐐","latestComments": [{"id": "180123456789","text": "GOAT! 🐐","ownerUsername": "fan123","ownerProfilePicUrl": "https://scontent-...jpg","timestamp": "2023-08-15T12:35:00.000Z","repliesCount": 5,"replies": [],"likesCount": 120,"owner": {"id": "987654321","is_verified": false,"profile_pic_url": "https://scontent-...jpg","username": "fan123"}}],"displayUrl": "https://scontent-iad3-1.cdninstagram.com/v/t51.2885-15/312345678_123_n.jpg?...","audioUrl": "https://scontent-iad3-1.cdninstagram.com/v/t50.1234-16/123_n.mp4?...","alt": "Video of Cristiano Ronaldo scoring a goal.","videoViewCount": 5000000,"videoPlayCount": 5000000,"childPosts": [],"musicInfo": {"artist_name": "cristiano","song_name": "Original audio","uses_original_audio": true,"should_mute_audio": false,"should_mute_audio_reason": "","audio_id": "987654321012345"},"isCommentsDisabled": false,"downloadedVideo": "",}
Example Output — Sidecar/Carousel Post
(Note: If a sidecar post contains a video and passes the _is_reel check, it is parsed just like a standard Video post. The script does not recursively fetch the child media nodes from the timeline edge, so the childPosts array will remain [].)
Field Reference (Complete)
| Field Name | Type | Applies To | Description |
|---|---|---|---|
id | String | All | Unique media ID. |
type | String | All | Hardcoded to "Video". |
shortCode | String | All | Alphanumeric shortcode used in the URL. |
caption | String | All | Full post caption. |
hashtags | Array[String] | All | Extracted hashtags from the caption. |
mentions | Array[String] | All | Extracted mentions from the caption. |
url | String | All | Direct link to the post on Instagram. |
commentsCount | Integer | All | Total comment count. |
dimensionsHeight | Integer | All | Original video height. |
dimensionsWidth | Integer | All | Original video width. |
images | Array[String] | All | All available resolutions of the video cover. |
videoUrl | String | All | URL of the MP4 video file. |
likesCount | Integer | All | Total like count. |
timestamp | String | All | ISO-8601 creation timestamp. |
ownerFullName | String | All | Display name of the creator. |
ownerUsername | String | All | Username of the creator. |
ownerId | String | All | Numeric user ID of the creator. |
isPinned | Boolean | All | True if pinned to profile. |
productType | String | All | Media format (e.g., "clips"). |
videoDuration | Float | All | Video length in seconds. |
inputUrl | String | All | The targeted profile URL. |
firstComment | String | All | The text of the top recent comment. |
latestComments | Array[Object] | All | Detailed array of recent top comments. |
displayUrl | String | All | Primary high-res cover image URL. |
audioUrl | String | All | Direct progressive audio track URL. |
alt | String/Null | All | Accessibility alt-text. |
videoViewCount | Integer | All | Total view count. |
videoPlayCount | Integer | All | Total play count. |
childPosts | Array | All | Always empty ([]). |
musicInfo | Object | All | Audio track metadata. |
isCommentsDisabled | Boolean | All | True if comments are turned off. |
transcript | String | All | Auto-generated transcript text. |
downloadedVideo | String | All | Always empty (""). |
How does it work?
- Dynamic User Info Extraction: It begins by making a standard HTTP GET request to the target profile URL using the residential proxy. Using regex, it parses the returned HTML to extract the
profile_id(numericuser_id) and the user'sfull_name. - GraphQL API Exploitation: Instead of parsing HTML feeds, it utilizes Instagram's internal GraphQL endpoint (
/graphql/query/). It passes a hardcodeddoc_id(7950326061742207) mapped to the profile media timeline query, feeding it theuser_id. - Pagination: The API responds with JSON containing an
end_cursorand ahas_next_pageboolean inside thepage_infonode. The scraper continuously loops, injecting theend_cursorinto thevariablespayload for the next request untilhas_next_pageis false orresultsLimitis reached. - Media Filtering: The raw JSON edges are passed through
_is_reel(), which verifies fields like__typename == "GraphVideo",is_video == True, orproduct_type == "clips". Anything that doesn't pass is safely discarded. - Incremental Data Streaming: Data is not hoarded in memory. Using Apify's
Actor.push_data(), every successfully parsed Reel is immediately saved to the dataset.
How does Instagram Reels Scraper differ from the official Instagram API?
| Feature | Instagram Graph API (Official) | Instagram Reels Scraper |
|---|---|---|
| Account Requirement | Facebook App, Business Account, API Approval | None (Fully anonymous via proxies) |
| Setup Time | Days/Weeks for approval | Instant |
| Target Flexibility | Only accounts you own / have tokens for | Any public profile |
| Rate Limits | Extremely strict (hourly quotas) | Scalable (limited only by proxies/delays) |
| Music Info & Audio URLs | Not provided | ✅ Provided |
| View / Play Counts | Limited availability | ✅ Provided |
Rate Limits & Error Handling
- Request Delay: To simulate human browsing behavior, the script pauses for
requestDelayseconds (default 1.5s) between pagination calls. - HTTP Errors: If a page request fails (e.g., HTTP 429 Too Many Requests or 404 Not Found), the scraper logs a warning and gracefully stops pagination for that specific user, preserving all previously scraped data.
- JSON Decoding Errors: Handled seamlessly. If Instagram serves a blocked HTML page instead of a JSON response, the scraper breaks the loop without crashing the Actor.
- Proxy Rotation: The Apify Residential Proxy network automatically handles IP rotation to minimize rate limiting and geographic blocking.
Legal Considerations
The Instagram Reels Scraper extracts publicly available data. However, web scraping may violate Instagram's Terms of Service. You should use this tool responsibly, avoid aggressive polling, and ensure your scraping activities comply with all applicable local laws and data privacy regulations (e.g., GDPR, CCPA). This information does not constitute legal advice.
Frequently Asked Questions
Does it require an Instagram account?
No. By default, it scrapes public data anonymously using residential proxies. However, you can optionally provide a cookieHeader from an active session to access private accounts you follow.
How many posts can I scrape?
You can scrape the entire profile history by setting resultsLimit to 0. Bear in mind that massive accounts may take a long time to paginate.
Does it handle carousel/sidecar posts?
It only extracts sidecar posts if they contain a video element (acting as a Reel). Standard photo carousels are ignored.
What if a username is private?
If the account is private, the GraphQL endpoint will return an empty timeline unless you provide a valid cookieHeader belonging to an account that follows the private user.
Can I change the output filename?
On the Apify platform, data is pushed to the Key-Value store and Datasets rather than a local file, so you can export the dataset via the Apify Console to any format or filename.
What Python version is required?
The script utilizes modern asyncio and typing features, requiring Python 3.9 or higher.
What happens when Instagram changes its API?
Since it relies on an internal GraphQL doc_id, changes to Instagram's web client may break the scraper. Regular maintenance and updates to doc_id and header structures will be required over time.
Can I scrape multiple users?
Yes, the usernames input accepts an array of strings. The scraper will process each profile sequentially.
Troubleshooting
- Empty results / Stopping at Page 1: Instagram may be requesting a login challenge. Ensure that Apify Residential Proxies are active. Alternatively, provide a valid
cookieHeader. - 429 Too Many Requests: You are scraping too fast. Increase the
requestDelayparameter (e.g., to 3.0 or 5.0 seconds). doc_idnot found errors: Instagram updated its query hashes. TheGQL_PARAMS['doc_id']insidemain.pyneeds to be updated by inspecting a browser's network tab.- UnicodeEncodeError on Windows: Ensure your terminal is set to UTF-8. The scraper uses standard logging which may clash with older command prompts.
Changelog / Version History
- v1.0.0: Initial release. GraphQL integration, Apify SDK wrapper, and automatic Residential Proxy injection.