Instagram Comment Scraper with Sentiment
Pricing
from $1.75 / 1,000 results
Instagram Comment Scraper with Sentiment
Scrape Instagram comments from single post URLs or from an account's recent posts, with a sentiment label and score on every comment. $1.725 per 1,000 comments: 33% below the Free plan price of apify/instagram-comment-scraper, and the same flat rate on every plan.
Pricing
from $1.75 / 1,000 results
Rating
0.0
(0)
Developer
itnlab
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
21 hours ago
Last modified
Categories
Share
Scrape Instagram comments from an account's recent posts at a flat $1.75 per 1,000 comments for every buyer, with a sentiment label and score already on every comment.
No second pipeline, no second API bill. Each row arrives as positive, neutral or negative with a confidence score, so "what did people actually say about this launch" is one run rather than a scrape followed by a classification job.
Two kinds of input, and they can be mixed
Give it a post URL — https://www.instagram.com/p/DCMUrLltVlM/, or the /reel/ and /tv/ spellings of the same thing — and it reads the comments under exactly that post. Give it an account — https://www.instagram.com/nasa/ or nasa — and it walks that account's most recent posts, collecting the comments under each. One list may hold both, and the same post named twice is collected once.
Since 3 September 2026. Before that a post URL was refused, because the query behind a single post was reachable only to a signed-in visitor; it is not any more, so it is a target.
What is still refused, by name and with a reason rather than as an empty dataset: hashtag pages, place pages, stories, /tagged/ URLs, the reels home feed (instagram.com/reels/ with no post after it) and Instagram-wide search. Those are outside what a logged-out visitor can see at all, which is not a limit this Actor can lift.
How to use the Instagram comment scraper
- Paste post URLs (or profile URLs / handles) into Instagram posts or reels URLs (
directUrls). - Set Up to [number] of comments (
resultsLimit) — up to 5,000 per post. - Leave Include replies (
includeNestedComments) off — see the FAQ. - Press Start.
Those are the whole form: the same three fields as apify/instagram-comment-scraper, so an input written for it runs here unchanged. An account in directUrls reads the comments under its 12 most recent posts (one feed page), so an account run is roughly 12 × resultsLimit comments at most. The collector paces itself at about one comment per second per post, deliberately, because a client that transacts at a constant rate for twenty-four hours is not a person.
How it compares
What this listing does that the others on the Store do not: comments come back one row each with sentimentLabel and sentimentScore on them. Sentiment is sold here and only here — the sibling listings, Instagram Scraper and Instagram Profile Scraper, return no sentiment columns. A run of this listing writes comment rows and nothing else.
Prices below marked measured come from runs made on 2 September 2026 against an identical list of public accounts; those marked published are the vendor's own figure and were not re-tested here. Rows left as — are outside that Actor's scope rather than a shortcoming.
| Feature | This Actor | apify/instagram-scraper | apify/instagram-profile-scraper | apify/instagram-comment-scraper | apidojo/instagram-scraper |
|---|---|---|---|---|---|
| Pricing plan | pay per result | pay per result | pay per result | pay per result | pay per result |
| Price per 1,000 profiles or posts | — | $2.70 (Free plan, tiered) | $2.60 (Free plan, tiered) | — | $0.50 (published) |
| Price per 1,000 comments | $1.75 (flat) | $2.70 (Free plan - it charges per result, whatever the row) | — | $2.60 (Free plan, tiered) | — |
| Sentiment label + score on every comment | ✔️ | ❌ | ❌ | ❌ | ❌ |
| Usable on the Apify free plan | ✔️ | ✔️ | ✔️ | ✔️ | ❌ (demo only, 10 items) |
| Profile URLs | ✔️ | ✔️ | ✔️ | ❌ | ✔️ |
| Single post URLs | ✔️ | ✔️ | ❌ | ✔️ | reels URLs (published) |
| Hashtag, place, audio URLs | ❌ | hashtag + place (published) | ❌ | ❌ | ✔️ |
| An error row for every failed input | ✔️ | ✔️ (published) | ✔️ (published) | ✔️ (published) | ❓ |
parentCommentUrl on comment rows | ✔️ (null, as theirs is) | — | — | ✔️ (published) | — |
hashtags, mentions, taggedUsers, dimensions* on post rows | ✔️ (tagged accounts minimised; on Instagram Scraper) | ✔️ (published) | ✔️ (published) | — | ✔️ (published) |
How many comments you get
resultsLimit is a number of comments per post, and it is a promise: ask for 1,000 and a run returns 1,000, or every comment the post exposes when that is fewer. A post with 145 comments answers with 145 rows and no error.
Measured 7 September 2026 on p/Dc6zTucHTv8 (@kimkardashian): three consecutive runs asking for 1,000 comments, three runs returning exactly 1,000.
Where fewer come back it is Instagram's doing, not this Actor's, and the number to compare against is not commentsCount. That is Instagram's own total and it counts replies and filtered comments a logged-out reader is never served — the same post declares ~4,350 and its logged-out connection carries ~3,350. This Actor also does not take Instagram's first "there are no more" for an answer: the page that announced the end is fetched again before a run reports one, because an unconfirmed end was measured arriving hundreds of comments early. When a walk still ends short, the run log names the post, what was asked for, what came back and what Instagram declares, so a short answer never has to be guessed at.
Pricing
Pay per comment, no platform usage charged on top.
| Result | Price each | Per 1,000 | apify/instagram-comment-scraper, Free plan |
|---|---|---|---|
| Comment | $0.00175 | $1.75 | $2.60 |
A run of this Actor writes comment rows and nothing else, so this is the only rate it can charge.
One flat rate, for everybody. $1.75 per 1,000 — no plans, no tiers, no volume brackets, and no Apify platform usage charged on top. That is 32% below the $2.60 that apify/instagram-comment-scraper charges its Free-plan buyers (read from Apify's public API, 17 September 2026); their rate moves with the subscription a buyer is on, and ours does not move at all. The sentiment label on every row is not priced separately at all: no comparable listing on the Store sells it, so there is no rate of theirs to hold it against.
A post that turns out to have no comments costs nothing — you pay for comment rows, not for asking.
Output example
One comment row, exactly as it lands in the dataset. Values are from a real run on 10 September 2026 against a public post:
{"postUrl": "https://www.instagram.com/p/Dc6zTucHTv8","commentUrl": "https://www.instagram.com/p/Dc6zTucHTv8/c/18010741988975472","id": "18010741988975472","text": "Зустрічааайййтеееее 🙌","ownerUsername": "kalytsynskyi","ownerProfilePicUrl": "https://scontent.cdninstagram.com/v/t51.82787-19/631648810_...jpg","timestamp": "2026-09-10T14:32:50.000Z","repliesCount": null,"replies": null,"parentCommentUrl": null,"likesCount": 0,"owner": {"username": "kalytsynskyi","profile_pic_url": "https://scontent.cdninstagram.com/v/t51.82787-19/631648810_...jpg","is_verified": false,"id": "48010607833","full_name": null,"is_mentionable": null,"is_private": null,"profile_pic_id": null,"latest_reel_media": null},"sentimentLabel": "positive","sentimentScore": 0.9}
Fourteen keys, and the list is closed. The first twelve are
apify/instagram-comment-scraper's, under its names, in its order, with its
nulls — diffed key for key against a run of that Actor on 10 September 2026. The
last two are sentimentLabel and sentimentScore, which are the whole reason to
pick this Actor over that one. Nothing else is on the row, so an existing
pipeline reads these rows unchanged and a spreadsheet built on that Actor's
columns keeps working.
Thirteen until 14 September 2026. The fourteenth is parentCommentUrl, the
last column of the reference row this Actor did not write. It is null on every
row, and that is not a placeholder: only top-level comments are served to a
logged-out reader, so no comment collected here has a parent. Same argument as
repliesCount below — the column is theirs, the null is honest, and a consumer
switching over finds the field where they left it instead of losing it from an
export.
A failed input writes a row too. A URL that cannot be reached, or one this
Actor refuses by name, produces a row carrying inputUrl, url, error,
errorDescription and requestErrorMessages rather than disappearing — so fifty
URLs in is always fifty rows out, and which three of them died is a filter rather
than a diff. Error rows are not comment rows and are not charged as comments.
repliesCount and replies are null here and null there. Instagram renders
no comment replies to a logged-out reader and does not count them either,
measured on 217 comment nodes across three posts on 4 September 2026: the reply
count came back null on every single one. A repliesCount: 0 would be an
invented measurement. includeNestedComments is refused with that explanation
rather than accepted and ignored.
ownerProfilePicUrl and owner/profile_pic_url are signed URLs that expire
in four to five days, in this Actor and in the reference one. They are a lease on
the image, not a copy of it: fetch them during the run or not at all.
Earlier runs of this Actor wrote six more fields — postId,
postShortCode, postOwnerUsername, dataType, collectedAt and inputUrl —
and they were removed on 10 September 2026 so that the row equals the reference
scraper's plus the sentiment pair. Everything they carried is still reachable:
the shortcode is in postUrl, the run's input and timing are in the run's own
log and input record, and a caller who needs Instagram's numeric media id can
read it off a post row's id in Instagram Scraper.
Input example
The same input as apify/instagram-comment-scraper, unchanged — post URLs, comments per post, and the replies flag left off:
{"directUrls": ["https://www.instagram.com/p/Dc6zTucHTv8"],"includeNestedComments": false,"resultsLimit": 500}
That object is apify/instagram-comment-scraper's own published example, pasted here unchanged and run as-is. Its form is three fields and this one is the same three — checked field for field against its published input schema on 15 September 2026, and pinned in tests/test_actor_variants.py so the day either side moves, the suite says so.
That is up to 500 comments from that one post, about $0.86. There is no resultsType to set and nothing else to fill in: this listing returns comments. An account instead of a post — ["https://www.instagram.com/nasa/"] with "resultsLimit": 100 — is 12 posts × up to 100 comments, at most 1,200 comments, about $2.07.
Sentiment
Every comment carries sentimentLabel (positive / neutral / negative) and sentimentScore (0–1 confidence).
Scores describe the collected sample, not every comment that exists. resultsLimit is a cap per post, so a post with more comments than you asked for is sampled and any distribution you compute over it is a sample statistic — the run log names the post, what was asked for and what came back, rather than making you guess.
sentimentLabel can be null, and when it is, that is the honest answer rather than a failure to report. The classifier is asked in batches; a batch that comes back unreadable is asked a second time, and if the label still does not arrive the comment ships without one instead of with a guess. Comments are what you paid for and the label is derived from them, so a labelling problem never costs you the comment. In practice this is rare — 2,000 comments measured on 11 September 2026 came back with 2,000 labels — but code that reads this field should treat it as nullable, which is what the dataset schema declares.
FAQ
Can I get replies to comments? No, and includeNestedComments is refused rather than ignored. Measured on 3 September 2026 across Instagram's own JavaScript bundles: the comment connection a logged-out visitor can read returns top-level comments and a reply count, and every query that would expand a thread is behind the login wall. Accepting the flag and returning top-level comments anyway would make a run look like it had walked the threads and found them empty.
What about isNewestComments? Accepted, and it does nothing. It is not on this form, since 15 September 2026 — a tickbox whose own label says it has no effect is not a control. Comments arrive in the order Instagram's own connection serves them and are not reordered here; the key is still accepted so an input copied from another Actor runs unchanged instead of failing on an unknown key.
Why did a profile return nothing? Private accounts expose their header and nothing else. The run reports it as a failed target with the reason rather than as an empty success.
How fresh is it? Answers come from a snapshot rather than a live call at read time, and the run log records that snapshot's age. collectedAt is not one of the fourteen keys: it describes the run rather than the comment, which is why it left the row on 10 September 2026.
Is this legal? Public data only. You are responsible for how you use it, including under GDPR where the comments concern people in the EU.
Related
- Instagram Scraper — the same engine with profiles, posts and reels in front, at the same $1.75 per 1,000.
- Instagram Profile Scraper — handles in, one row per account with its posts nested, at the same $1.75 per 1,000.