# VK Posts & Comments Scraper - No Login (`memo23/vk-posts-comments-scraper`) Actor

Scrape public VK posts and their comment threads — author, text, likes, shares, views, media, plus commenter names and replies. Filter any wall by keyword or date. Works with handles, community URLs, owner IDs, and post links. No VK login. JSON/CSV, monitoring mode included.

- **URL**: https://apify.com/memo23/vk-posts-comments-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Social media, Automation, Agents
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.60 / 1,000 vk posts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## VK Posts & Comments Scraper

<p align="center">
  <img src="https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/vk-posts-comments-logo.png" width="140" alt="VK Posts &amp; Comments Scraper">
</p>

The fastest way to turn public VK walls into structured post data — **including the comments no other VK scraper delivers**.
Start from any handle, profile or community URL, owner ID, or direct post link, and get clean post rows with author, text, engagement, media, and an optional inline comment thread. No VK login, no cookies, no credentials.

### Why Use This Scraper?

- ✅ Every VK entry point — handles, profile/community URLs, owner IDs, `club…` forms, wall URLs, direct post links
- ✅ **Comments included** — commenter name + profile link, text, date, likes, and thread structure on every post
- ✅ Full engagement per post — likes, shares, views, plus author with verified badge
- ✅ Keyword filter — narrow any wall to posts containing your term, so you only pay for matches
- ✅ Date-window filters that also stop pagination early, so you never pay for posts you don't want
- ✅ Monitoring mode — schedule it and receive only posts you haven't seen before
- ✅ Works without VK credentials — public walls and posts only
- ✅ One row per post, export as JSON, CSV, Excel, XML, or feed it to the API / webhooks

### Overview

The VK Posts & Comments Scraper is built for social-media monitoring teams, market researchers, and agencies who need structured post data from VK (vk.com) — the dominant social network in Russian-speaking markets.

The output is post-shaped rows. Whether you start from a community URL, a personal profile handle, an owner ID, or a direct post link, the resulting dataset is a stream of post rows — comments are attached inline on their parent post row (as a `comments` array), not scattered as separate rows. That keeps one post = one row, which is what spreadsheet and BI workflows expect.

### Supported Inputs

#### Target types

| Target type | Pattern | Example |
|---|---|---|
| Handle / screen name | `{handle}` | `durov`, `kinopoisk` |
| Profile / community URL | `https://vk.com/{handle}` | `https://vk.com/kinopoisk` |
| Owner ID | `{id}` (negative = community) | `1`, `-108468` |
| Club / public / event form | `club{id}`, `public{id}`, `event{id}` | `club22822305` |
| Wall URL | `https://vk.com/wall{ownerId}` | `https://vk.com/wall-108468` |
| Direct post URL | `https://vk.com/wall{owner}_{post}` | `https://vk.com/wall-108468_3539459` |

#### Copy-pasteable input

```json
{
  "targets": [
    "durov",
    "https://vk.com/kinopoisk",
    "club22822305",
    "https://vk.com/wall-108468_3539459"
  ],
  "maxItems": 100,
  "includeComments": true
}
```

#### Unsupported inputs

- ⚠️ VK-wide keyword search across the whole network needs a real account. Filtering **inside the walls you list** works out of the box via `searchQuery`; searching all of VK works only if you supply your own token in `vkAccessToken`.
- ❌ Private profiles, hidden walls, login-only content
- ❌ Direct video/photo file downloads (media **metadata and URLs** are returned)

### Use Cases

| Audience | Use case |
|---|---|
| **Brand & PR teams** | Monitor what communities post about your brand in Russian-speaking markets — and what people say in the comments |
| **Market researchers** | Bulk-export posts + audience reactions from competitor and industry communities |
| **Media & OSINT analysts** | Track official channels and public figures with post history and engagement over time |
| **Content teams** | Mine high-engagement posts and comment sentiment for content ideas |
| **Agencies** | Deliver client-ready VK datasets on a schedule without writing scrapers |

### How It Works

![How It Works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-vk.png)

1. **Input** — add any mix of VK handles, profile/community URLs, owner IDs, or direct post links
2. **Auto-classify** — each target is routed to the right resolver automatically
3. **Walk the wall** — posts are collected page by page with author, text, date, engagement, and media metadata
4. **Optional comments** — with `includeComments`, each post's visible comment thread is fetched and attached inline
5. **Output** — one row per post in your dataset, ready for JSON/CSV/Excel export, API access, schedules, and webhooks

### Input Configuration

#### Input fields

| Field | Type | Required | Notes |
|---|---|---|---|
| `targets` | `array<string>` | yes | VK handles, URLs, owner IDs, club forms, or post URLs — mixed freely |
| `searchQuery` | `string` | optional | Keep only posts containing this text. Applies inside the targets above, or across all of VK when `vkAccessToken` is supplied |
| `vkAccessToken` | `string` | optional | Your own VK API token. Only needed for VK-wide search; leave empty for normal runs |
| `maxItems` | `integer` | optional | Max posts saved across the whole run (default `100` in the UI) |
| `maxItemsPerTarget` | `integer` | optional | Per-wall cap; empty lets the global max control the run |
| `includeComments` | `boolean` | optional | Attach each post's visible comments inline (default `false`) |
| `maxCommentsPerPost` | `integer` | optional | Cap comments saved per post; empty saves all visible ones |
| `publishedAfter` | `string` (date) | optional | Only posts on/after this date; also stops pagination early |
| `publishedBefore` | `string` (date) | optional | Only posts on/before this date |
| `monitoringMode` | `boolean` | optional | Skip posts already delivered to you on previous runs |
| `resetMonitoringState` | `boolean` | optional | One-shot: forget the "already seen" record and rebuild the baseline |
| `maxConcurrency` | `integer` | optional | Parallel page fetches (default `10`) |

#### Common scenarios

**1. Latest posts from a community, with comments**

```json
{
  "targets": ["https://vk.com/kinopoisk"],
  "maxItems": 50,
  "includeComments": true,
  "maxCommentsPerPost": 20
}
```

**2. Several walls, capped per wall, posts only**

```json
{
  "targets": ["durov", "club22822305", "-108468"],
  "maxItems": 300,
  "maxItemsPerTarget": 100
}
```

**3. Scheduled monitoring — only new posts since the last run**

```json
{
  "targets": ["https://vk.com/kinopoisk"],
  "monitoringMode": true,
  "includeComments": true
}
```

Run it on an Apify schedule; the first run seeds your baseline, every later run returns (and charges for) only posts you haven't received before.

### Output Overview

Each dataset item is one VK post row containing:

- **Core fields** — `postId`, `ownerId`, `sourceUrl`, `text`, `dateRaw`, `postedAt`, `scrapedAt`, `target`
- **Author** — name, VK profile URL, avatar URL, verified badge
- **Engagement** — `likes`, `shares`, `views` (parsed numbers plus VK's raw display values)
- **Media** — attachment image URLs, video links, outbound links, repost flag + quoted text
- **Comments** (when `includeComments: true`) — inline `comments` array with commenter name + profile URL + avatar, text, date, likes, thread parent, and permalink

All target types resolve to the same post shape. Fields VK doesn't expose for a given post (e.g. views on very old posts) are `null` rather than invented.

### Output Samples

#### Community post with comments

```jsonc
{
  "target": "https://vk.com/kinopoisk",
  "postId": "-108468_3539459",
  "ownerId": "-108468",
  "sourceUrl": "https://vk.com/wall-108468_3539459",
  "author": {
    "name": "Кинопоиск",
    "profileUrl": "https://vk.com/kinopoisk",
    "avatarUrl": "https://sun1-95.userapi.com/…",
    "verified": true
  },
  "text": "Отмененный сиквел «Корпорации монстров» хотели посвятить Майку и Салли в мире людей…",
  "dateRaw": "two hours ago",
  "postedAt": "2026-07-10T20:50:53.775Z",
  "likes": 42, "likesRaw": "42",
  "shares": 12, "sharesRaw": "12",
  "views": 16000, "viewsRaw": "16K",
  "isRepost": false,
  "images": ["https://sun9-77.userapi.com/…"],
  "videoUrls": [],
  "outboundLinks": [],
  "commentsScraped": 5,
  "comments": [
    {
      "commentId": "-108468_3539461",
      "threadOfCommentId": null,
      "author": {
        "name": "Ivan Pryakhin",
        "profileUrl": "https://vk.com/id844885971",
        "avatarUrl": "https://sun1-17.userapi.com/…"
      },
      "text": "Почему даже Pixar об этом с 2001 года не рассказал…",
      "dateRaw": "yesterday at 11:25 pm",
      "postedAt": "2026-07-09T23:25:00.000Z",
      "likes": null,
      "commentUrl": "https://vk.com/wall-108468_3539459?reply=3539461"
    }
    /* …4 more comments… */
  ],
  "scrapedAt": "2026-07-10T22:50:53.777Z"
}
```

#### Personal profile post (posts-only run)

```jsonc
{
  "target": "durov",
  "postId": "1_2418560",
  "ownerId": "1",
  "sourceUrl": "https://vk.com/wall1_2418560",
  "author": { "name": "Pavel Durov", "profileUrl": "https://vk.com/durov", "verified": true },
  "text": "Наблюдаю, как несмотря на проливной дождь, по Невскому проспекту…",
  "dateRaw": "1 May 2018",
  "postedAt": "2018-05-01T12:00:00.000Z",
  "likes": 48000, "likesRaw": "48K",
  "shares": 1152,
  "views": 9100000, "viewsRaw": "9.1M",
  "images": [],
  "scrapedAt": "2026-07-10T22:50:57.710Z"
}
```

### Key Output Fields

#### Post core

- `postId`, `ownerId`, `sourceUrl`, `target`, `text`, `dateRaw`, `postedAt`, `scrapedAt`

#### Author

- `author.name`, `author.profileUrl`, `author.avatarUrl`, `author.verified`

#### Engagement

- `likes` / `likesRaw`, `shares` / `sharesRaw`, `views` / `viewsRaw`

#### Media & links

- `images[]`, `videoUrls[]`, `outboundLinks[]`, `isRepost`, `repostText`

#### Comments (when `includeComments: true`)

- `comments[].author.{name, profileUrl, avatarUrl}`, `comments[].text`
- `comments[].postedAt`, `comments[].likes`, `comments[].threadOfCommentId`, `comments[].commentUrl`
- `commentsScraped` — how many comments were saved for the post

### FAQ

#### Does this scraper need my VK login or cookies?

No. It reads the public, server-rendered VK pages and never asks for credentials, cookies, or tokens.

#### Do you return post rows or comment rows?

Post rows. Comments are attached inline as a `comments` array on their parent post, so one post is always one dataset row — cleaner for CSV and BI tools.

#### How many comments do I get per post?

The comments VK exposes to anonymous visitors — the visible thread on the post page (typically the most recent top-level comments plus their visible replies). Very long threads are returned partially; that's a VK limitation for any scraper working without your login, and this is still the only VK actor that returns comments at all. Use `maxCommentsPerPost` to cap them further.

#### Are the like/view counts exact?

VK displays large counts abbreviated ("48K", "9.1M"). The scraper returns both the parsed number (`likes: 48000`) and VK's raw display value (`likesRaw: "48K"`). Small counts are exact.

#### Can I use this as a VK keyword search scraper?

Partly, and the distinction matters. Set `searchQuery` and the scraper keeps only posts containing that text — but the search runs **inside the targets you list**, not across all of VK. Searching the whole network requires a logged-in account, so nobody can offer it without your credentials.

In practice the scoped version is what monitoring work needs: give it the communities and profiles you care about plus a brand or product term, and you get the matching posts with their comments.

```json
{
  "targets": ["kinopoisk", "club22822305"],
  "searchQuery": "сериал",
  "maxItems": 100
}
```

If you do want the whole network, bring your own VK token. Leave `targets` empty, set `searchQuery`, and put the token in `vkAccessToken` — the run then searches all public VK instead of the walls you named. VK restricts network-wide search to real accounts, which is why this cannot be offered without a token of your own. The token is used for that run and never stored.

```json
{
  "targets": [],
  "searchQuery": "telegram",
  "vkAccessToken": "vk1.a.…",
  "maxItems": 100
}
```

#### Why did some posts come back with zero comments?

Those posts have commenting switched off. VK exposes this per post, and the scraper checks it before asking for the thread, so a closed post returns `commentsScraped: 0` instead of an error. Pavel Durov's wall is the best-known example: the posts carry six-figure like counts but no readable comments. You are never charged a comment event for them.

#### Can I scrape private profiles or hidden walls?

No. Only publicly available walls and posts are accessible. Private, hidden, deleted, or login-only content is skipped with a log message and never charged.

#### How do I get only new posts on a schedule?

Enable `monitoringMode` and run the actor on an Apify schedule. The actor keeps a private per-user record of delivered post IDs; each run returns only posts you haven't seen (and you're only charged for those). Use `resetMonitoringState` once if you ever want to rebuild the baseline.

#### What happens when a target cannot be read?

Private, deleted, or restricted walls are logged and skipped, and nothing is charged for them. If every target fails, the run ends as **failed** rather than reporting success with an empty dataset — so a run that returns nothing is never quietly billed as a good one.

### Support

Found a bug or have a feature request? Open a ticket on the actor's [Issues tab](https://console.apify.com/actors/memo23~vk-posts-comments-scraper/issues) — I typically respond within 24 hours.

### Additional Services

Need a custom export shape, deeper comment coverage, another VK surface (videos, communities directory), or scheduled delivery to your warehouse? I do tailored work — open an issue or contact me through Apify.

### Explore More Scrapers

If you found this useful, you might also like:

- [**Facebook Public Group Posts & Comments Scraper**](https://apify.com/memo23/facebook-public-group-posts-scraper) — public FB group posts + comments, no cookies
- [**LinkedIn Posts Scraper**](https://apify.com/memo23/linkedin-posts-scraper) — profile + company posts without cookies
- [**Instagram Comments Scraper**](https://apify.com/memo23/apify-instagram-comments-scraper) — post/reel comments incl. replies
- [**YouTube Comments Scraper**](https://apify.com/memo23/youtube-comments-scraper) — video comments with replies
- [**Reddit Scraper**](https://apify.com/memo23/reddit-scraper) — posts and users around any topic

Full list at [apify.com/memo23](https://apify.com/memo23).

***

### 🤖 For AI Agents & LLM Apps

**What it does:** returns public VK (VKontakte) wall posts as one row per post, with the comment thread attached inline when asked. No VK account, cookie, or token is required from the caller.

**Minimal tested input**

```json
{
  "targets": ["kinopoisk", "club22822305", "https://vk.com/wall1_2442097"],
  "maxItems": 20,
  "includeComments": true,
  "maxCommentsPerPost": 10
}
```

**Accepted target forms:** handle (`durov`), community (`club1`, `public1`, `event1`), numeric owner ID (`-108468`), wall URL, and direct post URL (`https://vk.com/wall1_2442097`). Mixed freely in one run.

**Output fields (flat):** `target`, `postId`, `ownerId`, `sourceUrl`, `author{name,profileUrl,avatarUrl,verified}`, `text`, `postedAt`, `dateRaw`, `likes`, `likesRaw`, `shares`, `sharesRaw`, `views`, `viewsRaw`, `isRepost`, `repostText`, `images[]`, `videoUrls[]`, `outboundLinks[]`, `comments[]`, `commentsScraped`, `scrapedAt`.

**Comment entries:** `commentId`, `author`, `text`, `postedAt`, `likes`, `threadOfCommentId`, `commentUrl`.

**Billing:** one `vk-post` event per saved post, one `vk-comment` event per saved comment, plus the standard actor-start event. Skipped and failed targets are not charged.

**Behaviour worth planning around:**

- `searchQuery` filters **within the listed targets**. VK-wide search needs the user's own `vkAccessToken`; with it, leave `targets` empty to search all of VK. Never invent or guess a token — ask the user, or stay scoped.
- Posts with commenting disabled return `commentsScraped: 0`, not an error.
- `postedAt` is ISO 8601 UTC; `dateRaw` is the raw Unix seconds.
- Owner IDs are negative for communities and positive for people.
- A run where every target failed exits **failed**, so an empty dataset is never reported as success.
- `monitoringMode` returns only posts not delivered on previous runs, which makes scheduled polling cheap.

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by VK Company Limited (V Kontakte LLC) or any of its subsidiaries. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available VK wall and post pages — no authenticated endpoints, paid features, or content behind the vk.com login wall. Users are responsible for ensuring their use complies with vk.com's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization.

***

### SEO Keywords

vk scraper, scrape vk, vk posts scraper, vk comments scraper, vk.com scraper, Apify vk, vkontakte scraper, vk wall scraper, vk community scraper, vk group posts export, social media monitoring russia, vk data extraction, vk post comments export, vk engagement data, russian social media scraper, vk brand monitoring, vk API alternative, vk posts to csv, social listening vk, vk osint tool

# Actor input Schema

## `targets` (type: `array`):

Public VK profiles, communities, handles, owner IDs, or direct post URLs. Mix them freely in the same list.

## `searchQuery` (type: `string`):

Only save posts from the targets above that contain this text. Leave empty to save every post. Searching all of VK is not possible without a login, so the filter always applies inside the targets you list.

## `vkAccessToken` (type: `string`):

Optional. Leave empty for normal use. Supplying your own VK API token unlocks VK-wide keyword search: set a Keyword filter and leave the targets list empty, and the run searches all of public VK instead of only the walls you named. VK restricts network-wide search to real accounts, so this cannot be offered without your own token. The actor never stores it.

## `maxItems` (type: `integer`):

Maximum number of VK posts to save across the whole run. Lower it for a small first test, raise it once the output matches your workflow.

## `maxItemsPerTarget` (type: `integer`):

Optional cap on posts saved from each individual wall or profile. Leave empty to let the total maximum control the run.

## `includeComments` (type: `boolean`):

When enabled, each post's page is fetched once and its visible comments are saved inline on the post row (author, text, date, likes, thread parent, permalink). VK exposes the most recent comments to anonymous visitors; very long threads are returned partially.

## `maxCommentsPerPost` (type: `integer`):

Optional cap on comments saved for each post. Leave empty to save all comments VK exposes for the post.

## `publishedAfter` (type: `string`):

Only save posts published on or after this date (YYYY-MM-DD). Also stops wall pagination early once older posts are reached, saving you time and charges.

## `publishedBefore` (type: `string`):

Only save posts published on or before this date (YYYY-MM-DD).

## `monitoringMode` (type: `boolean`):

When enabled, posts already delivered to you on previous runs are silently skipped and not charged. The first run after enabling monitoring returns every match — that builds your baseline. Combine with Apify's scheduler for a 'new posts since last run' feed.

## `resetMonitoringState` (type: `boolean`):

Drops your private 'already seen' record at the start of the run, so this run returns everything again and rebuilds the baseline. Turn it back off afterwards.

## `maxConcurrency` (type: `integer`):

Maximum number of pages fetched in parallel. The default is a good balance of speed and politeness.

## Actor input object example

```json
{
  "targets": [
    "durov",
    "kinopoisk"
  ],
  "searchQuery": "сериал",
  "maxItems": 100,
  "includeComments": false,
  "monitoringMode": false,
  "resetMonitoringState": false,
  "maxConcurrency": 10
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `comments` (type: `string`):

No description

## `allItems` (type: `string`):

No description

# 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 = {
    "targets": [
        "durov",
        "kinopoisk"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/vk-posts-comments-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 = {
    "targets": [
        "durov",
        "kinopoisk",
    ],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/vk-posts-comments-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 '{
  "targets": [
    "durov",
    "kinopoisk"
  ],
  "maxItems": 100
}' |
apify call memo23/vk-posts-comments-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/vk-posts-comments-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/uBRxjdbVw9KQplazI/builds/GeiBrAQciLkTiwyea/openapi.json
