Instagram Scraper: Profiles, Posts, Reels, Comments, Locations avatar

Instagram Scraper: Profiles, Posts, Reels, Comments, Locations

Pricing

from $0.20 / 1,000 results

Go to Apify Store
Instagram Scraper: Profiles, Posts, Reels, Comments, Locations

Instagram Scraper: Profiles, Posts, Reels, Comments, Locations

Scrape public Instagram data without a login: account profiles and bio links, the profile grid, the reels tab with play counts, single posts with engagement and comments, and location pages with the media posted there. HTTP-only, no browser.

Pricing

from $0.20 / 1,000 results

Rating

0.0

(0)

Developer

Faisal Ahdan naufal

Faisal Ahdan naufal

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Instagram Public Content Scraper

Scrape public Instagram data without a login and without a browser: account profiles, the profile grid, the reels tab with play counts, single posts with engagement and comments, and location pages with the media posted there.

Pure HTTP. No Playwright, no Selenium, no cookies to supply, no account.


Modes

Pick a mode, then give targets that match it.

ModeTargetsOne row perPaginates
profileusernames or profile URLsaccount
postsusernames or profile URLspost✅ unlimited
reelsusernames or profile URLsreel✅ unlimited
post_detailpost/reel URLs or shortcodespostcomments capped (below)
locationlocation ids or /explore/locations/ URLsmedia❌ one page
{
"mode": "reels",
"targets": ["nasa", "https://www.instagram.com/natgeo/"],
"maxItemsPerTarget": 60,
"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}

Read this before you pick a mode: the surfaces publish different fields

Instagram serves the same post with different fields depending on which page it came from. This is the most important thing to know about the output:

postsreelspost_detaillocation
Likes / comments
Play count
Caption, hashtags
Publish date
Video file URL
Comments

A field this actor could not get is null, never 0. A zero would silently wreck any average you compute. Rows affected by a surface limit also carry a _warning naming it and pointing at the mode that does publish the field.

The usual pattern: run posts or reels to enumerate an account cheaply, then feed the shortcodes you care about into post_detail for full engagement, timestamps and comments.


What it cannot do

Stated plainly, because these are platform limits, not bugs, and no setting works around them:

  • Hashtag scraping. /explore/tags/<tag>/ serves a sign-in page to logged-out visitors.
  • Search. Both the search page and the search API require a login.
  • Tagged-posts tab, followers/following lists, stories, and the contents of story highlights — all login-walled. (Highlight titles and covers do come through in profile.)
  • Deep comments. Instagram ships only the first ~13–15 comments to a logged-out viewer, whatever the post's real total. Its comment pagination endpoint requires a login. commentCount is the true total; commentsScraped is how many you actually got.
  • Location pagination. A location page serves one batch — about 63 media on the recent tab, 27 on ranked — and ignores any cursor. That is the whole harvest for a place, however large maxItemsPerTarget is.
  • Private accounts. Profile metadata is public; media is not. You get a profile row, and a PRIVATE_ACCOUNT diagnostic row from the media modes.

Also: Instagram Shop / product-catalog data does not exist on any public surface any more, so no mode here returns it. Note that productType values (feed, clips, igtv) are media formats, not shopping products — an easy field to misread.


Output

Every row carries the same envelope, so a mixed dataset stays queryable:

FieldMeaning
_modewhich surface produced the row
_inputthe target it belongs to
_sourcessr-relay-island (page 1, from the page itself) or api-graphql-replay (a paginated request)
_pagewhich page of the connection
_scrapedAtUTC ISO 8601
_warninga surface limit affecting this row
_error / _errorDetailset only on failure rows

Every input produces at least one row. A target that fails yields a diagnostic row rather than vanishing, so downstream joins stay idempotent: INVALID_INPUT, NOT_FOUND, PRIVATE_ACCOUNT, GATED_FOR_LOGGED_OUT, BLOCKED_AFTER_RETRIES, EMPTY_RESULT, UPSTREAM_SHAPE_CHANGED.

A reels row:

{
"_mode": "reels", "_input": "nasa", "_source": "ssr-relay-island", "_page": 1,
"shortcode": "DdEsW1ItqpI",
"url": "https://www.instagram.com/p/DdEsW1ItqpI/",
"mediaType": "VIDEO", "productType": "clips",
"likeCount": 94368, "commentCount": 1039, "playCount": 3992126,
"imageUrl": "https://scontent.cdninstagram.com/...",
"ownerUsername": "nasa", "ownerId": "4092263381",
"_warning": "caption_and_timestamp_not_published_on_this_surface: ..."
}

Instagram CDN URLs (imageUrl, videoUrl, profilePicUrl) are signed and expire — download anything you need to keep, promptly.


How it works, and why it keeps working

Instagram's public REST API (/api/v1/...) returns HTTP 401 require_login to anonymous callers as of September 2026 — identically across five TLS fingerprints, so it is an auth rollout rather than a bot defence. This actor does not use it.

Instead it reads the logged-out server-rendered Relay payload: warm the entity page, harvest the query id Instagram ships inline next to the data, and replay it against /api/graphql/ for pagination.

Because the query id is read from the page being scraped rather than pinned in the source, the usual persisted-query rot does not apply — when Meta rotates its ids, the next request picks up the new one automatically.

Full evidence, the measurements behind every limit above, and the traps worth knowing (/graphql/query returns 200 OK with null data; "404" appears in healthy pages) are in CRAWLING_METHOD.md.


Proxy and pacing

Instagram throttles anonymous traffic per IP and signals it with a 200 carrying a login wall rather than a 429. Residential proxy is strongly recommended. Without one, expect a handful of targets to succeed and then login walls; datacenter ranges are throttled sooner. On a block the actor rotates both the TLS profile and the proxy session, then retries with exponential backoff.

delaySeconds (default 2) paces targets. Lower it only behind rotating residential proxy — pacing keeps a run alive considerably longer than hammering does.


Scrapes only data Instagram serves to a logged-out visitor. No login, no credential use, no access to private accounts or restricted content. You are responsible for how you use the output, including under the GDPR/CCPA where personal data is involved.