Reddit Comments Scraper avatar

Reddit Comments Scraper

Pricing

$1.20 / 1,000 results

Go to Apify Store
Reddit Comments Scraper

Reddit Comments Scraper

Collect archived public Reddit post comments and nested replies by post URL, with timestamps, scores, and reply-tree links. Export the dataset as JSON or CSV.

Pricing

$1.20 / 1,000 results

Rating

0.0

(0)

Developer

MLG Data

MLG Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

Scrape public Reddit post comments and nested replies from a post URL, then export the resulting Reddit discussion data to JSON, CSV, or a spreadsheet. This Reddit API alternative reads a public archive of posts and comments, so it works without an account or authentication, while clearly showing when each record was archived.

The output begins with one parent post item and continues with comment items from the same thread. Each comment carries its parent identifier and reply depth, allowing a discussion to be reconstructed as a tree. You can provide several post URLs in one run and set both a per-post comment limit and an overall item limit. Public archive coverage varies by post and date; see Limits before using the output as a complete or current record of a conversation.

What data can you extract from Reddit?

The dataset contains two item types. dataType is post for the parent post and comment for a reply. Post context appears on every comment so a file containing several threads remains easy to filter. Fields that the archive does not provide are returned as null, with their names retained for compatibility with common comment exports.

FieldDescriptionExample
dataTypeItem kindcomment
idFull post or comment identifiert1_p93c1nf
parsedIdIdentifier without kind prefixp93c1nf
urlDirect item permalinkhttps://www.reddit.com/r/AskReddit/comments/1wd5nqd/.../p93c1nf/
postIdFull parent post identifiert3_1wd5nqd
parsedPostIdParent post identifier without prefix1wd5nqd
postTitleParent post titleWhat’s the worst video game that you have ever bought?
postUrlParent post permalinkhttps://www.reddit.com/r/AskReddit/comments/1wd5nqd/.../
postUpVotesArchived post upvotes19
postCommentsCountComment total in the archived post record230
subredditNameCommunity without the r/ prefixAskReddit
communityNameCommunity with the r/ prefixr/AskReddit
parsedCommunityNameCommunity without the prefix on comment itemsAskReddit
titlePost title on post itemsWhat’s the worst video game that you have ever bought?
bodyArchived post self text or comment textBattlefield 2042
bodyHtmlRendered comment text, if the source provides itnull
authorNamePublic username or deletion marker[deleted]
authorIdFull author identifier, if availablenull
parsedAuthorIdAuthor identifier without prefix, if availablenull
authorFullnameFull author identifier, if availablenull
authorFlairTextPublic author flair on a commentnull
authorPremiumArchived premium status, if availablenull
scoreArchived net score9
upvoteRatioPost upvote ratio on post items0.82
commentsCountPost comment total on post items230
parentIdFull identifier of the parent post or commentt3_1wd5nqd
parsedParentIdParent identifier without prefix1wd5nqd
parentKindWhether the parent is a post or commentpost
depthReply level, starting at zero0
isSubmitterWhether the commenter created the postfalse
commentUpVotesArchived comment upvotes9
controversialityArchived controversiality value0
totalAwardsReceivedArchived number of awards0
gildedArchived gilding count0
distinguishedPublic distinction, when presentnull
stickiedWhether the comment is pinnedfalse
scoreHiddenWhether its score is hiddenfalse
collapsedWhether the comment was collapsedtrue
collapsedReasonReason for collapse, when suppliednull
editedWhether an edit was recordedfalse
editedAtEdit time when availablenull
bodyLengthCharacter count of archived comment text16
wordCountWhitespace-separated word count2
ageHoursHours from creation to archive retrieval36.0
scorePerHourArchived score divided by that age0.25
commentCreatedAtComment creation time in UTC2026-09-11T04:11:29Z
postCreatedAtPost creation time in UTC2026-09-11T04:10:46Z
isNsfwWhether a post carries an 18+ flagfalse
isRemovedWhether the stored body is a removal markerfalse
archivedAtArchive retrieval time for this record2026-09-12T16:11:46Z

A post item has post-level fields such as title, upvoteRatio, commentsCount, and isNsfw. Comment items carry reply fields such as parentId, depth, edited, and commentCreatedAt. The dataset schema describes each field and its possible null value. Dates use UTC and an ISO 8601 string.

How to scrape Reddit comments

  1. Copy a public Reddit post URL. A normal /r/community/comments/post-id/.../ URL works, as does a permalink to one of that post’s comments. A short redd.it/post-id link also works.
  2. Add the URL to Post URLs. Add more URLs if you want several discussions in the same dataset. Duplicate references to the same post are processed once.
  3. Set Maximum comments per post to control the size of each thread. The default is 1,000. Set Maximum total items if the whole run needs a hard cap across all threads.
  4. Start the run. Each available post is written first, followed by archived comments in oldest-first order. Nested replies appear in the same dataset and can be connected with parentId.
  5. Download the dataset as JSON or CSV. For spreadsheet work, import the CSV and filter dataType to comment if you only need replies.

A comment permalink identifies its parent thread; it does not restrict the output to that one comment. The scraper retrieves the archived discussion for the entire post. For a single comment, filter the resulting dataset by id or parsedId.

Input

ParameterTypeDefaultDescription
postUrlsURL listEmpty; requiredPost URLs, comment permalinks, or short post links.
maxCommentsPerPostInteger1000Comment cap for each post, from 1 to 10,000. The parent post item is additional.
maxItemsInteger0Hard cap across all post and comment items. Zero removes the overall cap.
includeNSFWBooleanfalseInclude archived posts flagged as 18+ and their comments.
proxyConfigurationObjectPlatform proxyConnection settings for retrieving public archive records.

Example input for one discussion:

{
"postUrls": [
{"url": "https://www.reddit.com/r/AskReddit/comments/1wd5nqd/whats_the_worst_video_game_that_you_have_ever/"}
],
"maxCommentsPerPost": 150,
"maxItems": 151,
"includeNSFW": false
}

With these limits, the verified run produced 151 dataset items: one post and 150 comments. The post item counts toward maxItems, so set that value to at least one more than the number of comments you want from a single post. If you supply several URLs, maxCommentsPerPost resets for each post, while maxItems remains a run-wide cap.

Output example

This shortened item comes from the verified run above. The archive stored this comment as a top-level reply. The parentId therefore begins with t3_, and depth is zero. Additional columns described in the table are present in the full dataset item.

{
"dataType": "comment",
"id": "t1_p93c1nf",
"parsedId": "p93c1nf",
"body": "Battlefield 2042",
"postId": "t3_1wd5nqd",
"postTitle": "What’s the worst video game that you have ever bought?",
"subredditName": "AskReddit",
"parentId": "t3_1wd5nqd",
"parentKind": "post",
"depth": 0,
"score": 9,
"commentCreatedAt": "2026-09-11T04:11:29Z",
"archivedAt": "2026-09-12T16:11:46Z",
"isRemoved": false,
"url": "https://www.reddit.com/r/AskReddit/comments/1wd5nqd/whats_the_worst_video_game_that_you_have_ever/p93c1nf/"
}

The parent post record is a separate item with dataType: "post". Its id begins with t3_. In a multi-post run, group by postId; then use parentId to connect a reply to its parent. A missing parent can occur when the archive lacks that ancestor, so depth may be null for the affected branch. The original parentId remains available even then.

Use cases

  • Discussion research: Collect the text, timestamps, and reply structure of a known public thread. Separate top-level responses from follow-up conversations with depth and parentKind.
  • Product feedback review: Export replies to a product announcement or question. Group comments by parent to see which observations sparked longer exchanges.
  • Community reporting: Capture a dated snapshot of a public discussion, including archived scores and moderation markers. Retain archivedAt alongside the observations so reports do not imply a live reading.
  • Conversation mapping: Rebuild a reply graph using id and parentId. The two prefixes distinguish posts from comments without needing to parse URLs.
  • Editorial research: Collect direct comment links and creation times for later manual review. Filter removed bodies and hidden scores before quoting or summarizing a thread.
  • Spreadsheet analysis: Compare several known threads in one CSV by filtering on postId, subredditName, commentCreatedAt, or isSubmitter.

Use only public discussion data for these workflows. Public usernames can still be personal data in context. Handle exports according to the rules that apply to your project and location.

How much does it cost to scrape Reddit comments?

The configured result price is $1.20 per 1,000 dataset items. Each written post or comment is one item. The run’s 151 items therefore represent $0.1812 in result charges. A 1,001-item dataset, such as one post plus 1,000 comments, represents $1.2012. A 5,005-item dataset, such as five posts plus 5,000 comments, represents $6.006. These examples use the item price only; check the run details for the final account charge and any account-specific limits.

The per-post limit is a maximum, not a promise of that many comments. A small thread, an excluded 18+ post, or an incomplete archive can yield fewer items. A post with no archived comments can still produce its parent post item if the post record is available. Setting maxItems limits how many items can be written across the run and is useful when the number of comments is uncertain.

If a dataset is used for periodic monitoring, a new run is a new snapshot and writes new items. Charges are based on the items produced by that run. The scraper does not compare its results with prior datasets or charge only for changes. Keep a stable id key in your destination if you intend to merge repeated exports.

Tips for best results

Use a full post URL when possible. The important part is the post ID after /comments/; the title slug is only for readability. URLs copied from a comment within that thread also contain the post ID and work for the full discussion. Short post URLs in the redd.it/post-id form work as well. Links in the /s/ share format do not expose the post ID in the path and are not supported.

Start with a limit of 100 to inspect the available fields and archive coverage. Raise maxCommentsPerPost when the thread has more relevant material. The archive returns up to 100 comments per request, and the scraper moves through successive pages by creation time. Large threads require more requests and take longer. The postCommentsCount field comes from the archived post record, which may have been retrieved at a different time from the comments. It is context, not a guaranteed count of rows available to this scraper.

For several threads, keep a run-wide maxItems if you have a fixed dataset size in mind. Posts are processed in input order. Since a parent post is written before its comments, an overall cap can stop in the middle of a later thread. Increase the cap or run that thread separately if you need more of it.

When comparing score values, use archivedAt. The archive may have stored a comment shortly after publication, before voting settled. ageHours and scorePerHour are computed from the comment’s creation time and the archive retrieval time, not the current clock. This makes their meaning stable in a saved export but does not turn an old score into a live score.

Limits

This scraper uses a public archive because the public Reddit page, JSON listing, comment expansion route, alternate hosts, and feed routes were blocked or redirected to login during development. Archive records are historical snapshots. New posts may take time to appear; some comments, edits, removals, or whole threads may never be captured. The archive may be temporarily unavailable or rate limited. A successful run means the returned records were processed; it does not prove the entire live thread was captured.

The maximum input setting is 10,000 comments per post, but actual coverage depends on what the archive holds. Pagination uses a second-resolution creation timestamp. Extremely busy threads with more than 100 comments created within one second could leave a gap at a page boundary. The actor removes duplicate IDs within each post; it cannot recover records that are absent from the source.

The archive does not reliably provide full author identifiers, premium status, or rendered comment HTML. Those compatibility fields remain null. Replies whose parent is absent retain parentId, but their depth is null because the missing ancestor prevents an accurate depth calculation. Removed or deleted bodies may appear as [removed] or [deleted]; the scraper does not restore their original text. Post counts, scores, flags, and flair reflect the stored record and may differ from the live site.

Only public post and comment URLs are accepted. Subreddit listing pages, profile pages, search URLs, and /s/ share links are outside this input format. No account-required content is retrieved. An 18+ post is skipped unless includeNSFW is enabled; that flag does not override an unavailable archive record. Validate coverage against your intended use before drawing conclusions from comment counts or sentiment.

Automated use

The input and output are regular JSON, so a scheduled workflow can provide post URLs and read the resulting dataset. For example, a task could request: “Collect up to 200 archived comments from this public post and return the oldest ten top-level replies with their permalinks.” Another could request: “Run these three post URLs, then group the exported comments by postId and count replies with parentKind equal to comment.” Both tasks should carry archivedAt into any report that describes the discussion.

For repeat runs, store the original input and the run time beside your exported data. A comment’s id is a practical deduplication key for that thread across runs. The content or score for the same identifier may change if a later archive retrieval replaces an earlier snapshot. Decide whether your destination keeps the earliest version, latest version, or both before scheduling frequent runs.

FAQ

This actor reads public records, but you are responsible for using the data lawfully. Respect applicable terms, privacy rules, and the rights of people whose public comments you process. Do not use public usernames for personal-data misuse. If your project republishes text, consider the context and any removal or deletion markers.

Do I need an account or a proxy?

No account is required. The default connection settings use the platform proxy and were sufficient for the verified archive run. You can supply a different proxy configuration if your environment requires one. Proxy settings cannot make a missing archive record appear.

How fast is a run?

Time depends on the number of posts, the comment limit, archive response time, and rate limits. The verified 151-item run completed successfully, including a second comment page. A 10,000-comment request needs many more pages and should be expected to take longer. Judge speed from your own run details for your typical thread sizes.

Can I schedule and monitor it?

Yes. Use the platform’s schedule and run status features, then inspect item counts and logs. A completed run with very few items may reflect source coverage rather than a parsing error. Track archivedAt and the difference between postCommentsCount and exported comments when monitoring important threads.

Can I export to a spreadsheet?

Yes. Download CSV and open or import it in a spreadsheet. Filter dataType to separate posts from comments. postId, parentId, and ISO dates make it straightforward to group threads, build reply tables, and sort chronologically.

Why is a field empty?

Some properties do not exist in the public archive, and others are optional on Reddit. Author IDs, premium status, and rendered body HTML are currently null. Flair, edit times, collapse reasons, and distinctions are often null even for otherwise complete comments. A null depth means the archive did not provide enough parent records to calculate it safely.

No. The permalink contains the parent post ID, and the actor collects that post and its archived discussion. Filter by comment id after export when one reply is needed. This behavior also means several comment permalinks from the same post are deduplicated into one thread during a run.

Integrations

The resulting dataset can be read through the platform’s data endpoint, downloaded as JSON or CSV, passed to a webhook, or imported into a spreadsheet or database. Scheduled runs can refresh a discussion export, while stable id and postId values support merging and grouping downstream. Keep the archive retrieval time with each row so downstream displays explain when the record was observed.

Support

Open an issue on the Issues tab; we reply within 24h and add fields on request. Include a public post URL, the run link, and a short description of the missing or incorrect data so the report can be checked against the archived source.