Instagram Reels Scraper avatar

Instagram Reels Scraper

Pricing

$4.99/month + usage

Go to Apify Store
Instagram Reels Scraper

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

Neuro Scraper

Maintained by Community

Actor stats

1

Bookmarked

69

Total users

3

Monthly active users

15 days ago

Last modified

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 CategoryPublicly Available
Public User Profile InfoYes (Username, Full Name, User ID)
Reel Video & Audio URLsYes (Without watermarks)
Engagement MetricsYes (Likes, Views, Plays, Comments Count, Shares)
Captions, Mentions & HashtagsYes
Latest CommentsYes (Top threaded comments available on the node)
Music & Audio MetadataYes (Artist, Song, Mute reasons, Original Audio flag)
Private Account ContentNo (Unless valid cookieHeader with access is provided)
Historical Story DataNo

What data can I extract with Instagram Reels Scraper?

Identity & Ownership Fields

Field NameDescription
ownerIdThe unique numeric ID of the account that posted the Reel.
ownerUsernameThe handle/username of the creator (e.g., cristiano).
ownerFullNameThe display name of the creator.

Engagement & Media Metric Fields

Field NameDescription
likesCountTotal number of likes the Reel has received.
commentsCountTotal number of comments on the Reel.
videoViewCountTotal number of views.
videoPlayCountTotal number of plays (often identical to views).
sharesCountTotal number of times the Reel was shared/reshared.
isPinnedBoolean indicating if the Reel is pinned to the top of the profile.
isCommentsDisabledBoolean indicating if the creator disabled comments.

Content, Media & Comments Fields

Field NameDescription
idThe unique numeric ID of the Reel media.
shortCodeThe short alphanumeric code used in the URL (e.g., p/{shortCode}).
urlThe full public URL to the post.
inputUrlThe target URL provided as input to the scraper.
typeMedia type (Hardcoded to "Video").
productTypeUsually "clips", "reels", or "igtv".
captionThe full text caption of the Reel.
altAccessibility caption/alt-text, if available.
hashtagsArray of hashtags extracted from the caption.
mentionsArray of @mentions extracted from the caption.
timestampISO-8601 formatted timestamp of when the Reel was posted.
dimensionsHeightThe original height of the video in pixels.
dimensionsWidthThe original width of the video in pixels.
imagesArray of thumbnail/cover image URLs at various resolutions.
displayUrlThe highest resolution cover image URL.
videoUrlThe direct MP4 video URL.
videoDurationLength of the video in seconds.
audioUrlDirect URL to the progressive download of the audio track.
musicInfoObject containing artist_name, song_name, uses_original_audio, should_mute_audio, should_mute_audio_reason, and audio_id.
transcriptAuto-generated clips transcript, if available.
latestCommentsArray of objects representing the most recent comments (includes id, text, ownerUsername, timestamp, likesCount, etc.).
firstCommentThe text of the most recent comment.
childPostsArray for sidecar children (Always empty [] for this Reel scraper).
downloadedVideoPlaceholder 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, and videoDuration will be populated. The type is always set to "Video".
  • Image Posts: Ignored. The scraper's _is_reel function 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 nested childPosts array will remain empty ([]), and the media URLs will reflect the cover of the sidecar.

How to configure Instagram Reels Scraper

Configuration Options

ParameterTypeDefaultDescription
usernamesArray of Strings[]List of Instagram usernames or profile URLs to scrape.
resultsLimitInteger10Maximum number of Reels to extract per username. Set to 0 for unlimited.
cookieHeaderString""Optional raw Cookie string from an authenticated browser session to bypass strict blocks or scrape private profiles.
requestDelayFloat1.5Delay 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

  1. Prerequisites: Ensure you have Python 3.9+ installed and the required libraries: requests and apify.
  2. Setup Input: Pass your target profiles into the usernames array via the Apify Actor input UI or a local JSON input file.
  3. Set Max Items: Adjust resultsLimit to restrict how many videos you pull per profile (e.g., 100). Use 0 to scrape the entire account history.
  4. Run the Script: Run the Actor on the Apify Platform, or locally via the Apify CLI (apify run).
  5. 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 NameTypeApplies ToDescription
idStringAllUnique media ID.
typeStringAllHardcoded to "Video".
shortCodeStringAllAlphanumeric shortcode used in the URL.
captionStringAllFull post caption.
hashtagsArray[String]AllExtracted hashtags from the caption.
mentionsArray[String]AllExtracted mentions from the caption.
urlStringAllDirect link to the post on Instagram.
commentsCountIntegerAllTotal comment count.
dimensionsHeightIntegerAllOriginal video height.
dimensionsWidthIntegerAllOriginal video width.
imagesArray[String]AllAll available resolutions of the video cover.
videoUrlStringAllURL of the MP4 video file.
likesCountIntegerAllTotal like count.
timestampStringAllISO-8601 creation timestamp.
ownerFullNameStringAllDisplay name of the creator.
ownerUsernameStringAllUsername of the creator.
ownerIdStringAllNumeric user ID of the creator.
isPinnedBooleanAllTrue if pinned to profile.
productTypeStringAllMedia format (e.g., "clips").
videoDurationFloatAllVideo length in seconds.
inputUrlStringAllThe targeted profile URL.
firstCommentStringAllThe text of the top recent comment.
latestCommentsArray[Object]AllDetailed array of recent top comments.
displayUrlStringAllPrimary high-res cover image URL.
audioUrlStringAllDirect progressive audio track URL.
altString/NullAllAccessibility alt-text.
videoViewCountIntegerAllTotal view count.
videoPlayCountIntegerAllTotal play count.
childPostsArrayAllAlways empty ([]).
musicInfoObjectAllAudio track metadata.
isCommentsDisabledBooleanAllTrue if comments are turned off.
transcriptStringAllAuto-generated transcript text.
downloadedVideoStringAllAlways 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 (numeric user_id) and the user's full_name.
  • GraphQL API Exploitation: Instead of parsing HTML feeds, it utilizes Instagram's internal GraphQL endpoint (/graphql/query/). It passes a hardcoded doc_id (7950326061742207) mapped to the profile media timeline query, feeding it the user_id.
  • Pagination: The API responds with JSON containing an end_cursor and a has_next_page boolean inside the page_info node. The scraper continuously loops, injecting the end_cursor into the variables payload for the next request until has_next_page is false or resultsLimit is reached.
  • Media Filtering: The raw JSON edges are passed through _is_reel(), which verifies fields like __typename == "GraphVideo", is_video == True, or product_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?

FeatureInstagram Graph API (Official)Instagram Reels Scraper
Account RequirementFacebook App, Business Account, API ApprovalNone (Fully anonymous via proxies)
Setup TimeDays/Weeks for approvalInstant
Target FlexibilityOnly accounts you own / have tokens forAny public profile
Rate LimitsExtremely strict (hourly quotas)Scalable (limited only by proxies/delays)
Music Info & Audio URLsNot provided✅ Provided
View / Play CountsLimited availability✅ Provided

Rate Limits & Error Handling

  • Request Delay: To simulate human browsing behavior, the script pauses for requestDelay seconds (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.

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 requestDelay parameter (e.g., to 3.0 or 5.0 seconds).
  • doc_id not found errors: Instagram updated its query hashes. The GQL_PARAMS['doc_id'] inside main.py needs 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.