# YouTube Community Posts Scraper With Keyword & Date Monitoring (`simpleapi/youtube-community-posts-scraper`) Actor

An automation actor that extracts posts, polls, and comments from YouTube community tabs. It gathers post text, timestamps, likes, and engagement data, enabling audience analysis, sentiment tracking, and content strategy optimization for brands and creators.

- **URL**: https://apify.com/simpleapi/youtube-community-posts-scraper.md
- **Developed by:** [SimpleAPI](https://apify.com/simpleapi) (community)
- **Categories:** Lead generation, Social media, Videos
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### YouTube Community Posts Scraper With Keyword & Date Monitoring

Monitor the **Community tab** of any YouTube channel and get back only the posts that matter. This scraper turns a one-off channel scrape into a scheduled monitor: run it on a timer with delta mode enabled, and each run returns **only the new community posts** published since the last run. Narrow further with a keyword filter, an approximate date range, and a country (geo) context.

Most community-post scrapers dump the whole feed every run, leaving you to diff it yourself. This one remembers what it already emitted per channel, persisted across scheduled runs, so a daily monitor genuinely returns a daily delta instead of the same 50 posts over and over.

### What is YouTube Community Posts Scraper With Keyword & Date Monitoring?

It's an Apify actor that reads a YouTube channel's Community tab through a hybrid HTML + InnerTube API approach (Chrome TLS impersonation to avoid soft-blocks), and adds monitoring-specific features on top: `deltaMode` tracks every post ID it has already emitted per channel in a persistent Apify key-value store, so a scheduled run only pushes posts published since the last run — the very next identical run returns 0 new rows if nothing changed. A `keywordFilter` keeps only posts whose text contains a phrase, and `dateFrom`/`dateTo` bound posts by an approximate date derived from YouTube's own relative "2 weeks ago" style timestamps (YouTube exposes no exact date on Community posts, so this window is honestly labeled approximate).

### What data can I extract with YouTube Community Posts Scraper With Keyword & Date Monitoring?

| Field | Description |
| --- | --- |
| `postId` / `channelId` | Post's unique ID (used for delta-mode dedup) and the channel's ID. |
| `author` / `authorUrl` | Channel display name and canonical channel path. |
| `text` | Full post text (also the poll question for poll posts). |
| `publishedTime` | Relative published time exactly as YouTube shows it (e.g. `"2 weeks ago"`). |
| `likeCount` / `commentCount` | Abbreviated count strings (e.g. `"1.2K"`), or `null` when not shown. |
| `attachmentType` | `"video"`, `"image"`, `"poll"`, or `null` for text-only posts. |
| `pollChoices` | Poll answer options; empty array for non-poll posts. |
| `images` | Attached image URLs; empty array when none. |
| `videoThumbnail` | Thumbnail URL when the post attaches a video; `null` otherwise. |
| `sourceUrl` | The input channel URL this row came from. |

### Why not build this yourself?

YouTube's Community tab has no public API — this actor reads the same reverse-engineered `ytInitialData` + InnerTube `browse` continuation mechanism any scraper must use, but routes every request through Chrome TLS/JA3 impersonation and a soft-block detector (checking for a data-less shell, a consent interstitial, or "unusual traffic" wording) rather than trusting a 200 status code alone. The harder part to build yourself is the delta-tracking: persisting a per-channel seen-post-ID set across scheduled runs, correctly sized so the "recent window" scanned each run is neither too small (misses a post if the channel posted a lot since last run) nor unboundedly large (rescans the whole feed every time). This actor handles that state management for you.

One honest limitation: YouTube's Community posts show only a relative published time (`"3 days ago"`), never an exact timestamp — so `dateFrom`/`dateTo` filtering is necessarily approximate, off by up to a few days depending on when YouTube's own relative-time bucket rounds. This is disclosed in the input description rather than presented as exact filtering.

### How to use data extracted from YouTube Community Posts Scraper With Keyword & Date Monitoring?

- **Community managers** — run a scheduled delta-mode monitor on your own channel (or a competitor's) to get alerted only on genuinely new posts, not a repeated full dump.
- **Fan/news aggregation sites** — pull new Community posts from a set of creators on a schedule and republish or summarize only what's new.
- **Brand monitoring teams** — use `keywordFilter` to watch for a product or campaign name mentioned in a creator's Community posts.
- **Researchers** — collect a dated archive of a channel's Community activity using `dateFrom`/`dateTo` for a specific historical window.

### 🔼 Input sample

| Parameter | Required | Type | Description | Example |
| --- | --- | --- | --- | --- |
| `channelUrls` | Yes | array | Channel URLs to monitor (`@handle` or `/channel/UC...`). One per line or a comma-separated string. | `["https://www.youtube.com/@MrBeast"]` |
| `maxPosts` | No | integer | Posts to return per channel (1-10000). In delta mode, this is the size of the recent window scanned each run — only unseen posts inside it are emitted. Default `10`. | `10` |
| `deltaMode` | No | boolean | Track and skip previously-emitted post IDs (persisted per channel). First run returns all matches; the next identical run returns 0. Default `false`. | `true` |
| `keywordFilter` | No | string | Case-insensitive substring match against post text. Empty = keep every post. | `"giveaway"` |
| `dateFrom` / `dateTo` | No | string | ISO date bounds (`YYYY-MM-DD`). **Common pitfall:** YouTube only exposes relative published times, so these bounds are approximate — treat the boundary as fuzzy by a few days. | `"2026-07-01"` |
| `countryCode` | No | string | Two-letter code sent as `gl` in the InnerTube client context, fetching the feed as if from that country. Default `"US"`. | `"GB"` |
| `proxy` | No | object | Optional. Falls back to Apify RESIDENTIAL automatically on a block and retries on a fresh IP. Default direct. | `{"useApifyProxy": false}` |
| `requestTimeout` | No | integer | Per-request timeout in seconds (1-300). Default `15`. | `15` |
| `maxRetries` | No | integer | Retry attempts before switching proxy (1-10). Default `3`. | `3` |
| `retryDelay` | No | integer | Initial backoff between retries in seconds, doubling each attempt (0-60). Default `2`. | `2` |

```json
{
  "channelUrls": ["https://www.youtube.com/@MrBeast"],
  "deltaMode": true,
  "keywordFilter": "giveaway",
  "maxPosts": 20
}
```

### 🔽 Output sample

```json
{
  "channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
  "postId": "Ugkx1234567890abcdefg",
  "author": "MrBeast",
  "text": "New video dropping this Friday! Who's excited?",
  "publishedTime": "3 days ago",
  "likeCount": "142K",
  "commentCount": "8.1K",
  "attachmentType": "image",
  "images": ["https://yt3.ggpht.com/example.jpg"],
  "pollChoices": [],
  "sourceUrl": "https://www.youtube.com/@MrBeast"
}
```

### ▶️ Want to try other scrapers?

| Actor | What it does |
| --- | --- |
| [youtube-channel-keyword-research-scraper](https://apify.com/SimpleAPI/youtube-channel-keyword-research-scraper) | Research channels by keyword and SEO signal. |
| [youtube-video-details-comments-scraper](https://apify.com/SimpleAPI/youtube-video-details-comments-scraper) | Get video details and comments. |
| [youtube-search-scraper-channel-contact-links](https://apify.com/SimpleAPI/youtube-search-scraper-channel-contact-links) | Search YouTube and pull channel contact links. |

### How to extract YouTube Community posts programmatically

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("SimpleAPI/youtube-community-posts-scraper-keyword-date-monitoring").call(run_input={
    "channelUrls": ["https://www.youtube.com/@MrBeast"],
    "deltaMode": True,
    "maxPosts": 20,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["author"], item["publishedTime"], item["text"][:60])
```

Every run's dataset can also be exported straight to JSON, CSV, Excel or an API endpoint from the Apify Console — no code needed for a one-off pull.

### Is it legal to scrape YouTube Community posts?

Scraping publicly accessible data — including public Community tab posts — is generally lawful in the US under the precedent set in *hiQ Labs v. LinkedIn*, which held that scraping data not gated behind a login does not violate the Computer Fraud and Abuse Act. This actor reads only Community posts that are publicly visible with no login required. If you extract data tied to identifiable individuals, GDPR (EU) and CCPA (California) still govern what you do with it, so review your own use case.

### ❓ FAQ

**How does deltaMode actually avoid duplicate posts?**
It stores every emitted post's ID per channel in a persistent Apify key-value store (`community-seen-postids`). Each run loads that set, skips any post ID already in it, and saves the updated set at the end — so a scheduled run only pushes posts that weren't there last time.

**Why does the first delta-mode run return a lot of posts, and the next return zero?**
The first run has no seen-post history, so everything in the scanned window counts as new. If the channel hasn't posted anything since, the next run's scanned posts are all already in the seen set — 0 new rows is the correct, expected result, not a failure.

**How accurate is `dateFrom`/`dateTo` filtering?**
Approximate. YouTube's Community tab only ever shows a relative published time like "2 weeks ago," never an exact timestamp — the actor converts that into an approximate calendar date, which can be off by a few days depending on where YouTube's own rounding falls.

**What happens if maxPosts is set very high with deltaMode on?**
It sets how deep into the recent-posts window the actor scans each run — a very high value with deltaMode on means scanning further back each run, which is unnecessary once the channel's normal posting cadence is established; a value that safely exceeds posts-since-last-run is usually enough.

**Does keywordFilter search the whole post or just a snippet?**
It matches against the post's full text (case-insensitive substring), including the question text for poll posts.

**What if a channel's Community tab is empty or disabled?**
The actor logs that no posts were matched for that channel and moves on to the next one in `channelUrls` — it doesn't fail the whole run.

**How is this different from other YouTube Community post scrapers on Apify?**
As observed on the Apify Store on 2026-07-26, the Community post scrapers we reviewed return a full snapshot every run with no built-in deduplication across scheduled runs, and none offer approximate date filtering derived from YouTube's own relative timestamps.

### Conclusion

YouTube Community Posts Scraper With Keyword & Date Monitoring turns a full-feed scrape into a genuine scheduled monitor — new posts only, filtered by keyword and approximate date, with the seen-post state handled for you across runs.

# Actor input Schema

## `channelUrls` (type: `array`):

One or more YouTube channel URLs to watch. Accepts @handle URLs (youtube.com/@MrBeast) or /channel/UC... URLs. Add one per line, or paste a single comma-separated string. Each channel's Community/Posts tab is scanned.

## `maxPosts` (type: `integer`):

Posts to return per channel (1–10,000). With keyword/date filters on, the actor scans deeper into the feed to collect this many matches. In delta mode this is the size of the RECENT window it checks each run (only unseen posts in that window are emitted).

## `deltaMode` (type: `boolean`):

When ON, remembers every postId it has emitted in a persistent named store ('community-seen-postids', keyed per channelId) and skips them on later runs — so a scheduled run returns only posts published since last time. First run returns all matches; the very next identical run returns 0. Turn OFF for a full snapshot every run.

## `keywordFilter` (type: `string`):

Keep only posts whose text contains this phrase (case-insensitive substring match). Leave empty to keep every post.

## `dateFrom` (type: `string`):

ISO date (YYYY-MM-DD). Drops posts older than this. NOTE: YouTube only exposes relative times ('2 weeks ago'), so the age is APPROXIMATE — treat the boundary as fuzzy by a few days. Leave empty for no lower bound.

## `dateTo` (type: `string`):

ISO date (YYYY-MM-DD). Drops posts newer than this. Same approximate caveat as the 'on/after' date — derived from relative published times. Leave empty for no upper bound.

## `countryCode` (type: `string`):

Two-letter country code sent as `gl` in the YouTube InnerTube client context, so the feed is fetched as if from that country. Defaults to US.

## `proxy` (type: `object`):

Optional. Runs direct by default. Enable an Apify proxy group or a custom URL for higher volume; if it's blocked the actor falls back to Apify RESIDENTIAL and retries on a fresh IP.

## `requestTimeout` (type: `integer`):

Per-request timeout in seconds (1–300).

## `maxRetries` (type: `integer`):

How many times to retry a failing fetch before switching proxy (1–10).

## `retryDelay` (type: `integer`):

Initial backoff between retries in seconds; doubles each attempt (0–60).

## Actor input object example

```json
{
  "channelUrls": [
    "https://www.youtube.com/@MrBeast"
  ],
  "maxPosts": 10,
  "deltaMode": false,
  "countryCode": "US",
  "proxy": {
    "useApifyProxy": false,
    "apifyProxyGroups": []
  },
  "requestTimeout": 15,
  "maxRetries": 3,
  "retryDelay": 2
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped items in the Actor's default dataset.

## `summary` (type: `string`):

Run-level counters (matched/scanned/skipped, successful/failed channels, last processed URL) written to the default key-value store after each channel.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "channelUrls": [
        "https://www.youtube.com/@MrBeast"
    ],
    "keywordFilter": "",
    "dateFrom": "",
    "dateTo": "",
    "proxy": {
        "useApifyProxy": false,
        "apifyProxyGroups": []
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("simpleapi/youtube-community-posts-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "channelUrls": ["https://www.youtube.com/@MrBeast"],
    "keywordFilter": "",
    "dateFrom": "",
    "dateTo": "",
    "proxy": {
        "useApifyProxy": False,
        "apifyProxyGroups": [],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("simpleapi/youtube-community-posts-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "channelUrls": [
    "https://www.youtube.com/@MrBeast"
  ],
  "keywordFilter": "",
  "dateFrom": "",
  "dateTo": "",
  "proxy": {
    "useApifyProxy": false,
    "apifyProxyGroups": []
  }
}' |
apify call simpleapi/youtube-community-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,simpleapi/youtube-community-posts-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/miIfLIkg6MZRrXdlm/builds/R4eX61nxHVnJ9cymz/openapi.json
