name: reddit-automations description: How to automate Reddit operations using Chrome tools: scraping posts, extracting data with CSS selectors, and building Reddit automation workflows.
Reddit Automations
A collection of step-by-step guides for automating Reddit operations using Chrome browser tools (page_snapshot, inspect_element, extract_list, list_focusable, input, click).
1. Get a List of Posts from the Reddit Homepage
Overview
Scrape all posts from the Reddit homepage including title, URL, upvote count, and post timestamp.
Steps
-
Navigate to Reddit
navigate(url="https://www.reddit.com") -
Take a page snapshot (optional, to verify the page loaded and inspect refs)
page_snapshot()
2.5. Alternative way is to use list_focusable to know what is on the page.
-
Inspect a single post element to understand structure (do this once; skip if reusing known selectors)
inspect_element(ref="<article_ref_from_snapshot>")Reddit uses custom web components:
shreddit-postholds post metadata as attributes,faceplate-timeagoholds timestamps. -
Extract the full post list using
extract_list:extract_list( container="article", fields=[ "title=a[slot='title']", "url=a[slot='full-post-link']@href", "upvotes=shreddit-post@score", "time_posted=faceplate-timeago@ts" ] )
CSS Selectors Reference
| Field | Selector | Notes |
|---|---|---|
title |
a[slot='title'] |
Text content of the post title link |
url |
a[slot='full-post-link']@href |
Full absolute URL to the post |
upvotes |
shreddit-post@score |
Raw integer score from custom element attr |
time_posted |
faceplate-timeago@ts |
ISO 8601 timestamp string (UTC) |
Notes
- Reddit uses custom web components (
shreddit-post,faceplate-timeago) — standard selectors like.scorewon't work. - The
container="article"selector returns ~48 items; ~13 are ad/promo placeholders with empty fields — filter those out. - The
@scoreattribute is a raw number (e.g.948). Posts with 0 votes also return0. - The
@tstimestamp is ISO format, e.g.2026-06-26T12:37:00+00:00. - If the extracted list is empty or returns no valid posts, the page may not be in compact view. Re-navigate with
?feedViewType=compactViewappended:https://www.reddit.com/?feedViewType=compactViewand retry the extraction.
2. Fill a Post Submission Form on a Subreddit
Overview
Navigate to a subreddit's submit page, fill in the title, body text, and select a flair. Do NOT submit the post unless explicitly instructed.
Step-by-Step
2a. Open the Submit Page
navigate(url="https://www.reddit.com/r/<subreddit>/submit/")
Wait for the page to load, then use list_focusable to confirm the form is present. You should see ~26 focusable elements including the key form controls.
2b. Fill the Title
The title field is a custom element faceplate-textarea-input. Use its selector directly:
input(
selector="faceplate-textarea-input[name=\"title\"] >> #innerTextArea",
text="Your post title here"
)
Key detail: Always use this exact selector — faceplate-textarea-input[name="title"] >> #innerTextArea. The list_focusable output will show it as element #16 (textbox "*").
2c. Fill the Body (with Paragraphs)
The body is a contenteditable rich text editor inside shreddit-composer. Use the div[name="body"] selector and the input tool:
input(
selector="div[name=\"body\"]",
text="First paragraph.\n\nSecond paragraph.\n\nThird paragraph."
)
IMPORTANT — Paragraph formatting:
- Use
\n\n(double newline / empty line) between paragraphs. - The text is injected into a
contenteditablediv with Lexical editor, and\n\ngets converted to proper<p>tags — each paragraph becomes a separate<p>block. - Do NOT click the Markdown toggle button (inside
#post-composer_bodytext) — this causes the page to lose the form content and go blank. The button'saria-labelis localized (e.g. "Перемкнутися на Markdown" in Ukrainian, "Switch to Markdown" in English), so never target it by label. - Do NOT use Markdown formatting characters (
**bold**,# Heading, etc.) — input plain text only with blank lines for paragraph separation. - The
inputtool fills the contenteditable div correctly when using plain text with\n\nparagraph breaks. Verified working: empty lines between paragraphs result in separate<p>blocks with<br>elements.
2d. Select a Flair
-
Click the flair button:
click(selector="#post-flair-modal >> #reddit-post-flair-button") -
After the dialog opens, use
list_focusableto see available flairs and controls. The dialog will show focusable elements like:#post-flair-modal >> #flair-search— search textbox#post-flair-modal >> #post-flair-radio-input-no-flair— no flair#post-flair-modal >> #post-flair-radio-input-0— first flair#post-flair-modal >> #post-flair-radio-input-1— second flair#post-flair-modal >> #post-flair-radio-input-2— third flair, etc.#post-flair-modal >> #post-flair-modal-cancel-button#post-flair-modal >> #post-flair-modal-apply-button
-
Click the desired flair radio, e.g. for "Discussion" (index 2):
click(selector="#post-flair-modal >> #post-flair-radio-input-2") -
Click Apply to close the dialog:
click(selector="#post-flair-modal >> #post-flair-modal-apply-button")
2e. Submit Button
The submit button lives inside the custom element r-post-form-submit-button. Use the shadow-piercing selector from list_focusable:
click(selector="#submit-post-button >> #inner-post-submit-button")
Verified 2026-06-30. The outer ID #submit-post-button combined with >> #inner-post-submit-button to pierce the shadow DOM reaches the clickable inner button reliably. The button sits below the viewport; the click tool handles scrolling automatically.
2f. Detect Whether the Subreddit Allows Link Posts
Not all subreddits allow link posts. Some are text-only and reject type=LINK. Reddit's behavior makes this easy to detect.
Reddit's behavior: Navigating to /r/{subreddit}/submit/?type=LINK on a text-only subreddit triggers a server-side redirect to type=TEXT. On a link-allowed subreddit, the URL stays as type=LINK.
Detection methods (prefer A — one navigation tells you everything):
Method A — URL after navigation (simplest, one step):
navigate(url="https://www.reddit.com/r/<subreddit>/submit/?type=LINK")
→ Check the final URL:
- Contains
type=TEXT→ link posts NOT allowed (redirected) - Contains
type=LINK→ link posts allowed
Method B — Check for URL input field (most direct, post-navigation):
list_focusable()
Look for faceplate-textarea-input[name="link"] in the output. If present, link posting is allowed.
Method C — Check the post-type tabs:
In the tab bar (r-post-type-select[name="type"]), the Link tab occupies nth-of-type(3) when present. In text-only subreddits, it's absent entirely (gaps in the nth-of-type numbering).
Link form fields (when allowed):
| Field | Selector |
|---|---|
| Title | faceplate-textarea-input[name="title"] >> #innerTextArea |
| URL | faceplate-textarea-input[name="link"] >> #innerTextArea |
| Body (optional) | div[aria-label*="основного тексту"] or div[name="body"] |
Tested subreddits:
| Subreddit | Link posts | Behavior |
|---|---|---|
| r/AI_Agents | ❌ No | type=LINK → redirects to type=TEXT; Link tab missing |
| r/modelcontextprotocol | ✅ Yes | type=LINK stays; Link tab present (nth-of-type(3)) |
Form Elements Reference (from list_focusable)
| # | Role | Label | Selector |
|---|---|---|---|
| 16 | textbox | Title (*) | faceplate-textarea-input[name="title"] >> #innerTextArea |
| 17 | button | Add flair & tags (*) | #post-flair-modal >> #reddit-post-flair-button |
| 18 | textbox | Body text | div[name="body"] |
| — | button | Toggle Markdown | (avoid — breaks the form) |
| 22 | button | Submit | #submit-post-button >> #inner-post-submit-button |
Known Gotchas
- Selectors are language-independent; labels are not — Reddit UI labels, button text, and
aria-labelvalues are localized (e.g. "Публікувати" vs "Post", "Перемкнутися на Markdown" vs "Switch to Markdown"). Always use the selector fromlist_focusable— these are structural (based on IDs,nameattributes, shadow-piercing paths) and work regardless of locale. Never build a selector that includes a localized label, title, oraria-labelvalue. - Do NOT click the Markdown toggle button — it breaks the form; the page goes blank and
list_focusabledrops to 2 elements. Stay in rich text mode. The button is inside#post-composer_bodytextbut itsaria-labelis localized, so never target it. - Title selector must include
>> #innerTextArea— thefaceplate-textarea-inputalone won't work for input. - Body uses
div[name="body"]selector — not a textarea. Plain text with\n\nworks correctly. - Flair dialog is a modal — elements are scoped under
#post-flair-modal >>. Always prepend that prefix. - After submitting the page may stay on submit form — Reddit can redirect to the post or show an error banner. Check
page_snapshotafter submit to confirm outcome.
Fallback Strategy: When Something Goes Wrong
Reddit's UI is complex (custom web components, dynamic rendering, focus traps). If a click, input, or navigation doesn't work as expected:
1. Call list_focusable First
list_focusable()
This is the preferred diagnostic tool — it shows exactly which elements are interactive on the current page, their labels, and CSS selectors. Use it to:
- Confirm the form/page loaded correctly (26 elements = submit form OK; 2 elements = broken/blank page).
- Find the correct selector for an element that moved or changed.
- Verify a dialog opened (flair modal shows 12 elements with
#post-flair-modal >>prefix). - Discover new interactive elements you didn't know about.
2. Then Decide
Based on list_focusable output:
- Page blank / few elements? →
navigateback to the submit URL fresh. - Element not found with known selector? → use the selector from
list_focusableoutput instead. - Dialog didn't open? → the click target may have changed; inspect the button selector in
list_focusableand try again. - Element present but click fails? → try
page_snapshotfor a ref-based click, orinspect_elementto check if the element is disabled/hidden.
Future Sections (planned)
- Get posts from a specific subreddit
- Extract post comments
- Monitor a subreddit for new posts (event-based automation)
- Filter posts by keyword or upvote threshold
- Submit post and verify result