# VK Posts Scraper (`axiomworks/vk-posts-scraper`) Actor

Collect posts from public VK community walls and user profiles by URL, screen name, or ID. Get post text, timestamps, author details, attachment URLs, and exact engagement counts. Uses VK's public JSON API and requires no VK account, login, or API key.

- **URL**: https://apify.com/axiomworks/vk-posts-scraper.md
- **Developed by:** [Axiom Works](https://apify.com/axiomworks) (community)
- **Categories:** Social media, Marketing
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.26 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

**Returns:** one row per VK post with `postUrl`, `text`, `publishedAt`, `likesCount`, `repostsCount`, `commentsCount`, `viewsCount`, `authorName`.
**Input:** `{"targets": ["https://vk.com/team"], "maxItems": 50}`
**Best for:** monitoring VK communities and public figures, collecting post engagement for media research, building datasets of Russian-language social posts.

```json
{
    "postUrl": "https://vk.com/wall-22822305_1729945",
    "text": "Делаете классную рекламу и развиваете бизнес с VK? ...",
    "publishedAt": "2026-10-14T11:22:54Z",
    "likesCount": 107,
    "repostsCount": 4,
    "commentsCount": 34,
    "viewsCount": 52652,
    "authorName": "ВКонтакте"
}
```

### What does VK Posts Scraper do?

VK Posts Scraper is a VK (VKontakte) scraper that collects the posts on public VK walls: community pages (groups, public pages, events) and public user profiles. Give it a wall URL, a screen name or a numeric id, and it returns one row per post with the full text, publication and edit time, exact like, repost, comment and view counts, the pinned and repost flags, attachment types, photo, video and link URLs, and who published the post.

It reads VK's own public JSON API (the same one the logged-out vk.com web app uses), so the numbers are exact integers rather than the rounded "1.2K" shown in the browser. No VK account, login or API key is needed, and the Actor doesn't use a browser, so runs are fast and light.

Typical uses are tracking what a brand, media outlet or public figure posts on VK, measuring engagement across several communities, archiving a community's recent history, and feeding post text into translation, sentiment or topic analysis. Think of it as a simple VK API for wall posts that you can call from the Apify Console, your own code or an AI agent.

### What data can you get from VK?

| Field | Description | Example |
|---|---|---|
| `id` | Stable post ID (same as `postId`) | `-22822305_1729945` |
| `postId` | `<ownerId>_<post id>`; negative owner ids are communities | `-22822305_1729945` |
| `postUrl` | Link to the post on vk.com | `https://vk.com/wall-22822305_1729945` |
| `ownerId` | ID of the wall the post is on (negative for a community) | `-22822305` |
| `fromId` | ID of whoever published the post | `-22822305` |
| `text` | Post text as VK returns it, with VK inline markup such as `[id1\|Name]` kept; null when the post has no text | `Делаете классную рекламу...` |
| `publishedAt` | Publication time, ISO 8601 UTC | `2026-10-14T11:22:54Z` |
| `editedAt` | Last edit time, ISO 8601 UTC; null if never edited | `2026-10-14T12:13:54Z` |
| `likesCount` | Exact number of likes | `107` |
| `repostsCount` | Exact number of reposts | `4` |
| `commentsCount` | Exact number of comments | `34` |
| `viewsCount` | Exact number of views; null when VK doesn't report views | `52652` |
| `isPinned` | True for the post pinned at the top of the wall | `false` |
| `isRepost` | True when the post shares another post | `false` |
| `repostedPostUrl` | Link to the original post of a repost; null otherwise | `https://vk.com/wall-1_340364` |
| `attachmentTypes` | Types of attachments: photo, video, link, doc, poll, audio and so on | `["video"]` |
| `photoUrls` | Largest image URL of each attached photo | `["https://sun9-81.userapi.com/..."]` |
| `videoUrls` | Link to each attached video on vk.com | `["https://vk.com/video-22822305_456243482"]` |
| `linkUrls` | URL of each attached link | `["https://vk.cc/d2TzBl"]` |
| `authorName` | Community name, or the user's first and last name | `ВКонтакте` |
| `authorScreenName` | The author's screen name (the part after vk.com/) | `vk` |
| `authorType` | `group` for a community, `user` for a person | `group` |
| `input` | The target from your input that returned the post | `https://vk.com/team` |
| `scrapedAt` | When this run collected the post, ISO 8601 UTC | `2026-10-14T18:59:46Z` |
| `sourceUrl` | The VK API request the post came from (without any token) | `https://api.vk.com/method/wall.get?...&domain=team` |

Some fields depend on the post itself. Old posts, especially from before 2017, often have no view count, so `viewsCount` is null there rather than 0. A post that only shares another post usually has no text of its own; its `isRepost` is true and `repostedPostUrl` points to the original.

### How to use VK Posts Scraper

1. Open VK Posts Scraper in the Apify Console and go to the Input tab.
2. In "VK walls", add one or more walls. You can paste the address from your browser (`https://vk.com/rbc`), the mobile address (`https://m.vk.com/rbc`), a vk.ru address, a screen name (`rbc`, `durov`), a community id (`club1`, `public200000000`, `-25232578`, `https://vk.com/wall-25232578`) or a user id (`id1`, `1`).
3. Set "Maximum posts in total" (`maxItems`) to how many posts you want across all walls, and optionally "Maximum posts per wall" (`maxPostsPerTarget`) to spread the total over several walls.
4. Optionally set "Only posts published on or after" (`dateFrom`) to get only recent posts, and turn off "Include the pinned post" if you want only the regular timeline.
5. Click Start. When the run finishes, open the Output tab and export the posts as JSON, CSV, Excel, XML or RSS, or read them through the API.

Tips:

Walls are read newest post first, in the order you list them. If the first wall has more posts than `maxItems`, the later walls get nothing, so use `maxPostsPerTarget` when you want posts from every wall.

`dateFrom` stops reading a wall at the first regular post older than the date. The pinned post is the exception: it always comes first and can be years old, so it is skipped by the date filter without stopping the wall.

A wall that doesn't exist, is private, deleted or banned, or has no posts returns nothing. The run logs a warning for it and goes on with the next wall, so one bad target never sinks the others. If no wall returns posts, the run still finishes successfully and its status message says which target failed and why.

VK's API normally answers without a proxy. If your runs start getting blocked or rate-limited, turn on Apify Proxy in the Proxy section; blocked requests are then retried on a new IP automatically.

### Input

| Field | Type | Required | Description |
|---|---|---|---|
| `targets` | array of strings | Yes | VK walls to scrape: URLs, screen names, community ids (`club1`, `public123`, `-123`) or user ids (`id1`, `1`). |
| `maxItems` | integer | No | Maximum posts across all walls, 1-10000, default 50. |
| `maxPostsPerTarget` | integer | No | Maximum posts from each wall, default 100. |
| `dateFrom` | string | No | Only posts on or after this date, e.g. `2026-01-31` or an ISO date-time. Empty by default. |
| `includePinned` | boolean | No | Return the wall's pinned post, default true. |
| `proxyConfiguration` | object | No | Proxy settings. Default: no proxy. |

```json
{
    "targets": ["https://vk.com/team", "durov", "club1"],
    "maxItems": 100,
    "maxPostsPerTarget": 40,
    "dateFrom": "2026-01-01",
    "includePinned": true,
    "proxyConfiguration": { "useApifyProxy": false }
}
```

### Output

Each post is one item in the run's dataset. These are real items from a local run on `durov` (VK's founder's public wall, whose newest posts date from 2018):

```json
[
    {
        "id": "1_2431591",
        "postId": "1_2431591",
        "postUrl": "https://vk.com/wall1_2431591",
        "ownerId": 1,
        "fromId": 1,
        "text": "Михаил Светов, организатор прошедшего митинга за свободу интернета, объявил конкурс на наиболее вдохновляющую обработку видеоматериалов с митинга. Призовой фонд – 1 биткоин.\n\n#digitalresistance",
        "publishedAt": "2018-05-03T13:05:53Z",
        "editedAt": "2018-05-03T13:06:15Z",
        "likesCount": 26391,
        "repostsCount": 5695,
        "commentsCount": 0,
        "viewsCount": 9880333,
        "isPinned": false,
        "isRepost": false,
        "repostedPostUrl": null,
        "attachmentTypes": ["video"],
        "photoUrls": [],
        "videoUrls": ["https://vk.com/video1_456239033"],
        "linkUrls": [],
        "authorName": "Pavel Durov",
        "authorScreenName": "durov",
        "authorType": "user",
        "input": "durov",
        "scrapedAt": "2026-10-14T19:00:55Z",
        "sourceUrl": "https://api.vk.com/method/wall.get?v=5.199&client_id=6287487&count=4&offset=0&extended=1&domain=durov"
    },
    {
        "id": "1_2422169",
        "postId": "1_2422169",
        "postUrl": "https://vk.com/wall1_2422169",
        "ownerId": 1,
        "fromId": 1,
        "text": null,
        "publishedAt": "2018-05-01T15:19:57Z",
        "editedAt": null,
        "likesCount": 109438,
        "repostsCount": 5258,
        "commentsCount": 0,
        "viewsCount": 10306065,
        "isPinned": false,
        "isRepost": false,
        "repostedPostUrl": null,
        "attachmentTypes": ["photo"],
        "photoUrls": ["https://sun9-81.userapi.com/s/v1/ig1/Pu8awSIubU_Y8T1rJ34J_Vp0O8vHeIRwqxcLeTA2kUAY0nYPM1Z3g_4GroP8haJiSMh69WST.jpg?quality=96&blur=50,20&as=32x24,48x36,72x54,108x81,160x120,240x180,360x270,480x360,540x405,640x480,720x540,1080x810,1279x959&from=bu&u=bGESEAbiciYKstmnY0G7ZW5jP6_Fs5z5vvAoBt8gtbQ"],
        "videoUrls": [],
        "linkUrls": [],
        "authorName": "Pavel Durov",
        "authorScreenName": "durov",
        "authorType": "user",
        "input": "durov",
        "scrapedAt": "2026-10-14T19:00:55Z",
        "sourceUrl": "https://api.vk.com/method/wall.get?v=5.199&client_id=6287487&count=4&offset=0&extended=1&domain=durov"
    }
]
```

You can download the dataset as JSON, CSV, Excel, XML or RSS from the Output tab, or fetch it through the Apify API. In CSV and Excel, list fields such as `photoUrls` are spread over numbered columns.

### How much does it cost to scrape VK?

VK Posts Scraper is charged per result: you pay for each post returned, and nothing for walls that return no posts. `maxItems` caps how many posts a run can return, and so what it can cost. If you set a maximum cost per run in the run options, the Actor stops cleanly when that limit is reached and keeps the posts it already saved. See the Pricing tab for the current price.

### Use with AI agents (MCP)

Connect VK Posts Scraper to Claude, Cursor or any MCP client through the Apify MCP server:

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com/?tools=axiomworks/vk-posts-scraper"
        }
    }
}
```

Example prompts:

1. "Get the 30 latest posts from https://vk.com/rbc and list the five with the most views."
2. "Scrape the posts on the VK walls team and durov since 2026-01-01 and summarise what each one talks about."
3. "Compare average likes and reposts per post for VK communities club1 and public200000000 over their last 50 posts."

The agent sees the input fields described above. The only required one is `targets`; everything else has a sensible default.

### Integrations and API

Run VK Posts Scraper from your own code with the Apify API. Set `APIFY_TOKEN` to your Apify API token (send it in the `Authorization` header, never in the URL).

**Python**

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("axiomworks/vk-posts-scraper").call(run_input={"targets": ["https://vk.com/team"], "maxItems": 50})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["postUrl"], item["likesCount"], item["viewsCount"])
```

**JavaScript**

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('axiomworks/vk-posts-scraper').call({ targets: ['https://vk.com/team'], maxItems: 50 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**cURL**

```bash
curl -X POST "https://api.apify.com/v2/acts/axiomworks~vk-posts-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"targets": ["https://vk.com/team"], "maxItems": 50}'
```

You can also connect the Actor to Make, Zapier, n8n, Google Sheets, Slack or your own webhooks from the Integrations tab, and schedule it (for example every hour) to keep a running archive of a community's posts.

### FAQ

**Do I need a VK account or API key?**
No. The Actor uses the anonymous access that VK's own logged-out website uses, so it sees exactly what any visitor without an account can see. Private walls and members-only content are not available.

**Which walls work?**
Public community walls (groups, public pages, events) and public user profiles. A closed group, a private profile, or a deleted or banned page returns no posts, with a warning in the log saying the wall is private, deleted or banned.

**Why did my run return 0 results?**
The usual reasons are a typo in the screen name (VK answers that no page has that name), a private or deleted wall, an empty wall, or a `dateFrom` newer than the wall's latest post. The status message names the first failed target and the reason.

**Why is `viewsCount` empty for some posts?**
VK doesn't report views for many older posts, mostly from before 2017. The Actor keeps the field null in that case instead of guessing 0.

**Why does the text contain things like `[id1|Pavel]` or `[#alias|vk.cc/...|...]`?**
That is VK's inline markup for mentions and short links, kept exactly as VK returns it so you lose no information. Strip it in your own processing if you only need plain text.

**How fresh is the data?**
Every run reads the wall live, so counts are current at the time shown in `scrapedAt`.

**How many posts can I get from one wall?**
Up to 10,000 per run through `maxItems`, and VK pages through a wall 100 posts at a time. The Actor paces its requests at about one per second to stay polite to VK, so large runs take a few minutes.

**Can I get comments too?**
Not yet: this Actor returns posts with their comment counts. Tell us on the Issues tab if you need the comments themselves.

### Is it legal to scrape VK?

VK Posts Scraper collects only publicly visible posts, without logging in, and reads them through the same public interface VK's website uses for visitors. Posts on personal walls can contain personal data; you are responsible for having a legitimate reason to collect it and for handling it under the laws that apply to you, such as the GDPR. This is not legal advice; if in doubt, ask a lawyer.

VK Posts Scraper is an independent tool. It is not affiliated with, endorsed by or sponsored by VK (VKontakte).

### Related Actors

| Actor | What it does |
|---|---|
| [Telegram Channel Posts Scraper](https://apify.com/axiomworks/telegram-channel-posts-scraper) | Posts from public Telegram channels |
| [Bluesky Profile Scraper](https://apify.com/axiomworks/bluesky-profile-scraper) | Public Bluesky profiles |
| [Threads Search Scraper](https://apify.com/axiomworks/threads-keyword-search-monitor) | Threads posts that match a keyword |

### Feedback

Found a bug or need a field that isn't here? Open an issue on the Issues tab and we'll look at it.

# Actor input Schema

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

VK walls to scrape, one per line. Accepts a URL (https://vk.com/team, m.vk.com/rbc, vk.ru/rbc, https://vk.com/wall-25232578), a screen name (rbc, durov), a community id (club1, public200000000, -25232578) or a user id (id1, 1). A wall that doesn't exist, is private or is empty returns no posts and the run goes on with the next one.

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

Maximum number of posts to return across all walls, 1-10000, default 50. Walls are read in order, so the first walls can use the whole budget. The run stops as soon as this many posts are saved, and you are charged only for posts returned.

## `maxPostsPerTarget` (type: `integer`):

Maximum number of posts to take from each wall, at least 1, default 100. Works together with the total limit: the run stops at whichever is reached first.

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

Skip posts older than this date, e.g. '2026-01-31' (UTC midnight) or an ISO date-time. Reading a wall stops at the first older post that isn't pinned. Leave empty for no date filter (default).

## `includePinned` (type: `boolean`):

Return the wall's pinned post (it comes first and can be old), default true. Set to false to get only the regular timeline.

## `proxyConfiguration` (type: `object`):

Proxy to use for requests, default none. Turn on Apify Proxy (datacenter first, residential if still blocked) only if VK blocks or rate-limits your runs.

## Actor input object example

```json
{
  "targets": [
    "https://vk.com/team"
  ],
  "maxItems": 10,
  "maxPostsPerTarget": 100,
  "includePinned": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Dataset with one item per post, in the order found.

# 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": [
        "https://vk.com/team"
    ],
    "maxItems": 10,
    "maxPostsPerTarget": 100,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/vk-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 = {
    "targets": ["https://vk.com/team"],
    "maxItems": 10,
    "maxPostsPerTarget": 100,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/vk-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 '{
  "targets": [
    "https://vk.com/team"
  ],
  "maxItems": 10,
  "maxPostsPerTarget": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call axiomworks/vk-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axiomworks/vk-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/7Obs1cK8OYyDp9Ken/builds/6BJ9jdAuo358YQY9X/openapi.json
