Instagram Scraper - Profiles, Posts, Reels, Hashtags, Places avatar

Instagram Scraper - Profiles, Posts, Reels, Hashtags, Places

Pricing

from $3.50 / 1,000 profiles

Go to Apify Store
Instagram Scraper - Profiles, Posts, Reels, Hashtags, Places

Instagram Scraper - Profiles, Posts, Reels, Hashtags, Places

Gets 200 posts per account past Instagram's 12-post limit: 200 unique posts in 4 requests, zero repeats. Scrape Instagram profile data and Instagram reel play counts with no login. An empty run names one of 10 reasons instead of a silent empty table.

Pricing

from $3.50 / 1,000 profiles

Rating

0.0

(0)

Developer

Snow Leo Data

Snow Leo Data

Maintained by Community

Actor stats

0

Bookmarked

7

Total users

3

Monthly active users

7 days ago

Last modified

Share

Instagram Scraper — profiles, posts, reels, hashtags and places

Public Instagram data without a login, without cookies and without a browser. One table holds all four kinds of row: profiles, posts and reels, hashtags and places.

The point of this actor is the post walk. Instagram's own page stops at 12 posts per account for a logged-out visitor. This actor keeps going through the same feed query the site itself uses: 50 posts per request, cursor after cursor. Measured on 2026-09-17 on @nasa: 200 unique posts over 4 requests, zero repeats, reaching from 2026-09-16 back to 2026-04-10.

What you get

Profile — username, user id, full name, biography, followers, following, post count, verified, private, memorialised, profile picture, every bio link with its title, external URL, pronouns, account badges, Threads username, highlight count, whether the account has reels.

Post / reel — shortcode, post id, type (photo, video, carousel, reel), product type, date, likes, comments, plays, caption, hashtags, mentions, owner username, owner id, owner full name, owner verified, image URL, video URL, width, height, carousel item count and every carousel image, tagged users, co-authors, paid-partnership flag, comments-disabled flag, alt text, reel music title and artist, Instagram's topic pills, place name and coordinates.

Hashtag — the tag, its volume when Instagram states it, Instagram's own description of the tag, related keywords, plus the 12 posts of that page.

Place — id, name, latitude, longitude, plus the 18 posts of that page, each with likes, comments and dates.

What Instagram does not give a logged-out visitor

Written plainly, because you will hit these and should know beforehand:

  • Comments. No comment text is served without a login.
  • Followers and following lists. Only the counts.
  • Business category, contact e-mail and phone. Not in the logged-out page.
  • Stories and highlights content. Only the highlight count.
  • Hashtag coverage is partial. Instagram serves its logged-out hashtag page for some tags and the login wall for others: of 5 tags tried on 2026-09-17, 2 (travel, nature) returned 12 posts each and 3 (nasa, food, photography) returned the login wall. Closed tags are named in the run report; they do not fail the run. Tag pages also cannot be paged: the pagination query answers with null to a logged-out caller.
  • Hashtag volume is often missing. travel reports 3.9B, nature reports nothing at all. An absent number is null, never a guess.
  • Place pages stop at 18 posts. Their pagination query answers 401.
  • Play counts exist only for reels on the account's reels tab (up to 12 per account, switch on Add play counts for recent reels). Feed posts and post pages carry no view count at all.
  • Private and withheld accounts. Instagram answers with an error shell; the run report names the account and the reason instead of guessing.

How much of it costs what

Row kindHow it is fetchedWire traffic
Profileone page136–164 KB (141 KB typical)
Post / reel from an accountGraphQL feed, 50 per call4.6 KB per post
Hashtag + its 12 postsone page157 KB
Place + its 18 postsone page333 KB
Post opened for place, music, photo tagsone page per post149 KB

Pages are requested with gzip, which is why a profile page costs 141 KB instead of the 702 KB it weighs unpacked.

Watch mode

onlyNew remembers what earlier runs delivered and returns only what is new or changed, each row marked NEW or UPDATED in change_type. Signed CDN URLs change on every view, so they are deliberately left out of the change fingerprint — otherwise every post would look updated every morning and you would pay for the whole table again. A run that finds nothing new returns an empty dataset and says nothing-changed in the report.

Filters

minLikes, minComments, minFollowers, postedAfter, postedBefore, captionContains, postTypes. Two rules worth knowing:

  • Filters run before billing, so rows they remove are not charged.
  • A post whose owner hides like counts arrives with likes: null and is kept by minLikes — missing data is not a mismatch. The single exception is captionContains: a post with no caption cannot contain your phrase, so it is dropped.
  • postedAfter also stops the crawl, because the feed runs newest first. That is traffic you do not buy, not just rows you do not see.

maxItems caps the rows written to the dataset and never the crawl: with filters on, the crawl deliberately goes deeper so that a filtered run does not hand you an empty table.

An empty dataset always says why

no-input, nothing-requested, date-range-inverted, follower-filter-without-profiles, charge-limit-reached, nothing-changed, filtered-out, targets-not-available, nothing-collected, source-returned-nothing — one of these lands in empty_reason in the run report, and in the log as a warning. The first four are decided by your input alone and stop the run before a single request is made.

Proxy

Instagram blocks Apify's cloud addresses by name: measured 2026-09-17, a direct profile request from the cloud returns 200 and a 499 KB page with not one field in it, while the same page through a residential address returns the real data. The proxy input is therefore preset to residential, and you can change it like in any Apify actor. The run report tells you how many requests were made and how many bytes they cost.

Output

One flat table with a result_type column (profile, post, hashtag, location). compactOutput trims it to 18 columns for AI agents and spreadsheets; excludeEmptyFields drops nulls, empty lists and false values. The run report (REPORT in the key-value store) carries rows per kind, what each filter removed, which targets Instagram refused, the traffic bought and empty_reason.

What buyers of the big Instagram actors are asking for

Read on 2026-09-17 off the public issue boards of the seven largest Instagram actors on Apify — 156 open and closed tickets from people who already pay. Below is what they ask for and where this actor stands. Nothing here is a promise about their software; it is what their own buyers wrote.

What the tickets sayHere
"Post count came as empty for some accounts which actually do have posts", "Not retrieving count of posts for some instagram pages" — 2 ticketsposts_count is read out of the og:description line, because the page JSON carries all_media_count: null on every account measured
"Number of posts downloaded exceeds 12", "Returns only a few posts", "Detailed mode — not all posts returned", "Not retrieving all posts from date" — 4 tickets50 posts per feed call, cursor after cursor: 200 unique posts over 4 requests, zero repeats (measured 2026-09-17 on @nasa), up to 5000 per account
"videoPlayCount is null", "No views returned", "I do not see any Number of Views data", "Add videoPlayCount to the latest posts output" and nine more — 15 ticketsplays comes from the reels tab, the one logged-out surface that carries play_count. Switch: Add play counts for recent reels. Honest limit: Instagram lists about 12 reels there per account, and feed posts carry no view count at all
"Run marked as Succeeded but returns empty latestPosts", "empty successful datasets", "Common transient no items" — 7 ticketsan empty dataset always carries one of 10 named reasons in empty_reason; four of them stop the run before the first request
"restricted_page conflates three different situations — two of them carry no distinguishing field"every target Instagram refused is listed in the run report by name and reason, and does not fail the run
"Usernames containing .com resolve to a different account's profile (greedy .com stripping)"nike.com stays nike.com; only @, slashes and the query string are stripped
"Duplicated rows! The account has 68k followers, you extracted 118k"the post walk is cursor-based and de-duplicated by shortcode: zero repeats in the 200-post measurement
"Expose coauthor_producers so Instagram collaboration posts are detectable"coauthors ships on every post row
"paidPartnership is not returned"is_paid_partnership ships on every post row
"Add profile picture (favicon/avatar) to the response"profile_pic_url ships on every profile row
"Date filtered results unexpected", "Not retrieving all posts from date" — 3 ticketspostedAfter and postedBefore filter before billing, and postedAfter also stops the crawl, since the feed runs newest first
"Add maxRequestRetries / per-profile timeout — one blocked profile gates the whole run"a profile that fails is reported and skipped; the run continues. The per-request retry count is fixed at 3 and is not an input yet
"Business address not returned for business accounts that display address on profile", "Not showing mobile number and email" — 3 ticketsnot closed, and not promised: the logged-out business profile page carries no address, phone or e-mail (checked on @gopro)
"Mentions limited to 21 results", "Prefiltering Comments", "Instagram Search Scraper blocked"not closed: mentions, comment text and keyword search are all behind the login wall

Defaults

Running with the preset input returns the @nasa profile row and its 12 most recent posts. maxItems defaults to 50 so a trial run stays cheap; postsPerProfile defaults to 12 and goes up to 5000.