# Bilibili Popular Videos Scraper (`automation-lab/bilibili-popular-category-videos`) Actor

Export current Bilibili popular-board videos, creators, categories and engagement metrics. Filter locally by category ID for recurring snapshots; no login cookies or downloads.

- **URL**: https://apify.com/automation-lab/bilibili-popular-category-videos.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Videos, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.38 / 1,000 popular videos

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

## Bilibili Popular Videos Scraper

Export **Bilibili popular videos** for recurring China content-research snapshots. Collect current overall popular-board video identities, original titles, categories, creators and engagement metrics without buyer login cookies. Optional category IDs filter the fetched board locally; this is **not a separate category ranking**.

### What does it do?

Each run reads up to the first 200 positions of Bilibili's current overall popular board. It returns unique matching videos in board order, stopping at your result limit or source exhaustion. No video, thumbnail or audio is downloaded. Original Chinese text is preserved; no translation or AI inference is applied.

### Who is it for?

- Content researchers comparing category composition across daily snapshots.
- Marketing analysts following creators appearing on the popular board.
- Data teams exporting video IDs and engagement counts to a warehouse.

### Why use this Actor?

The output preserves stable BV identifiers and an observation timestamp for downstream joins. Creator identity, category and engagement come from the same board response, avoiding a separate detail request per video. Predictable scanning bounds and honest local filters distinguish this workflow from keyword search, individual-video enrichment and complete category rankings.

### Getting started

1. Open the Actor and select **Try for free** or **Start** in Apify Console.
2. Use the prefilled 20-video sample, or omit `maxResults` for the 50-video default.
3. Optionally enter numeric category IDs, such as `[21]` for 日常.
4. Start the run and inspect the **Videos** dataset view.
5. Export JSON, CSV or Excel using Apify's dataset tools.

Example input:

```json
{"maxResults":50,"categoryIds":[]}
```

### Input parameters

| Field | Default | Behavior |
|---|---|---|
| `maxResults` | 50 | Global maximum unique matching videos; integer 1–200. Zero is invalid, not unlimited. |
| `categoryIds` | `[]` | Positive numeric source category IDs; exact equality, ANY match. Empty means all categories. At most 50 IDs. |

Filters apply locally to the first 200 overall-board positions, not to a category-specific upstream endpoint. A narrow category can return fewer videos than requested, including zero. Discover category IDs in `categoryId`/`categoryName` output; the source's category names may change. Numeric strings are not accepted.

### Extracted data

| Fields | Meaning |
|---|---|
| `bvid`, `url`, `title` | Public BV ID, canonical video link and original title |
| `boardPosition` | One-based position in fetched overall-board pages, not category rank |
| `categoryId`, `categoryName` | Source category numeric ID and original name |
| `creatorId`, `creatorName` | Public creator mid and display name |
| `publishedAt`, `durationSeconds` | UTC publication timestamp and video duration |
| `views`, `likes`, `replies`, `shares`, `favorites`, `coins`, `danmaku` | Cumulative source-reported engagement counts; unavailable counts are null |
| `observedAt` | UTC start of the run's board collection |

Counts of replies/danmaku are metrics only: no comment text, reply threads or bullet-comment corpus is fetched.

### Output example

Example public record observed on October 8, 2026; titles, board positions and counts change over time.

```json
{
  "bvid":"BV1VeHQ6tEaS",
  "url":"https://www.bilibili.com/video/BV1VeHQ6tEaS",
  "title":"超市生存挑战后续！4人吃完整个超市赢100万美金！",
  "boardPosition":1,
  "categoryId":21,
  "categoryName":"日常",
  "creatorId":1027737427,
  "creatorName":"野兽先生MrBeast",
  "publishedAt":"2026-10-08T10:05:00.000Z",
  "durationSeconds":3466,
  "views":497720,
  "likes":44975,
  "replies":2123,
  "shares":2564,
  "favorites":14996,
  "coins":26311,
  "danmaku":3176,
  "observedAt":"2026-10-08T20:36:28.161Z"
}
```

The default dataset contains only video rows. The run-scoped `SUMMARY` key-value record reports actual `saved` rows, `collected` matching rows, `requested` limit, filters, scanning cap and scope note. `status` is `complete` or `budget_limited`; `budgetLimited` and `budgetReason` (`start_budget`, `item_budget`, or null) distinguish budget truncation from legitimate source/filter exhaustion. A successful run can still be budget-limited: inspect SUMMARY before treating it as a full requested snapshot.

### How much does it cost to extract Bilibili popular videos?

Pay-per-event pricing includes a **$0.004 start fee per valid run** and a fee per unique matching video saved. Proxy and platform processing are included; no external proxy account is needed. A valid run with no matching videos still incurs the start fee. Invalid inputs fail before charging.

| Apify spend tier | Per video |
|---|---:|
| FREE | $0.002645 |
| BRONZE | $0.0023 |
| SILVER | $0.001794 |
| GOLD | $0.00138 |
| PLATINUM | $0.00138 |
| DIAMOND | $0.00138 |

At BRONZE, estimates are $0.0155 for five videos, $0.119 for 50, and $0.464 for 200. Your applicable aggregate Store spend tier determines the item price, not a private per-Actor volume schedule. Confirm current prices in Console before running. There is no separate charge for metrics, category or creator fields.

### Limits and failure behavior

- Maximum ten sequential 20-video pages: 200 scanned positions per run.
- The board changes over time and may change during pagination; positions are observations, not an atomic ranking snapshot.
- Duplicate BV IDs are suppressed within a run. No persistent cross-run delta mode or historical archive is provided.
- The built-in route uses Apify residential proxy in CN, without buyer cookies. Temporary failures can retry up to three times per page with a fresh identity and bounded backoff.
- Source risk-control responses, malformed source data and exhausted requests fail the run, rather than masquerading as an empty successful snapshot.
- Results are collected before writing, so a later source error does not leave partial video rows. A failed run after a valid start can retain its start charge.
- The maximum charge budget also limits output. If it cannot cover the start fee or one video after starting, no source collection occurs. Otherwise the remaining item capacity caps collection. Only saved rows are charged; budget-limited runs retain paid rows and explicitly report partial output in SUMMARY/logs, even when the platform status is SUCCEEDED. Exact-fit output is not labeled partial merely because no budget remains.
- Category filtering can legitimately yield zero rows. This does not mean the category has no popular videos outside the scanned overall-board window.

### Integrations and recurring snapshots

Schedule daily runs in Apify and send datasets to a warehouse, Google Sheets, Make, Zapier or a webhook. Join by `bvid` and compare `observedAt` snapshots to identify newly observed videos or engagement changes. Calculate those differences downstream; the Actor itself does not send alerts or retain historical state. Keep full exports outside an LLM's context when using AI assistants.

### API use

Start once and retain the returned run ID. Poll that same run until terminal status, then read its `defaultDatasetId`; a run ID is not a result row. A failed run must not be reported as a complete snapshot.

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/automation-lab~bilibili-popular-category-videos/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
  -d '{"maxResults":50}'
```

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/bilibili-popular-category-videos').call({ maxResults: 50 });
if (run.status !== 'SUCCEEDED') throw new Error(`Run ${run.id}: ${run.status}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems({ limit: 50 });
console.log(items);
```

#### Python

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/bilibili-popular-category-videos').call(run_input={'maxResults': 50})
if run['status'] != 'SUCCEEDED':
    raise RuntimeError(run['status'])
items = client.dataset(run['defaultDatasetId']).list_items(limit=50).items
```

### MCP: Claude Code, Claude Desktop, Cursor and VS Code

Use the scoped hosted endpoint:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/bilibili-popular-category-videos"
```

Claude Desktop / Cursor MCP JSON configuration:

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/bilibili-popular-category-videos"}}}
```

VS Code uses the same URL under its `mcp.servers` configuration:

```json
{"mcp":{"servers":{"apify":{"type":"http","url":"https://mcp.apify.com?tools=automation-lab/bilibili-popular-category-videos"}}}}
```

Authenticate through your client's supported Apify flow. Example prompt: “Collect 20 current Bilibili popular videos and summarize their category composition; treat boardPosition as an overall-board observation.”

Discover actual names and argument schemas with scoped `tools/list`; selection also adds run/status/dataset/KV/abort helpers, not exactly one tool. For an authorized invocation, start once, retain the run/storage IDs and follow the same run. `call-actor` waits at most 45 seconds (default 30); choose a request timeout above that wait plus transport margin. If pending, poll the same run with bounded 2/4/8-second backoff capped at 10, and a total 120-second deadline. On timeout recover the known run, never restart just to poll. At the deadline report pending and its run ID.

After success, read explicit pages of 20 rows using `get-dataset-items`, offset and selected fields. Limit model context to at most 100 source rows and 64 KiB of serialized UTF-8 result content, whichever comes first, enforcing bytes host-side before model injection. If your client cannot intercept large responses, do not claim a hard byte guarantee. Stop at exhaustion or budget and disclose rows, continuation offset and truncation. Full exports stay in storage. Tool discovery transport bytes are not necessarily model-visible context; no numeric token savings are promised.

### Legality, responsible use and privacy

This Actor processes public video titles, public creator IDs/display names and aggregate metrics. It does not fetch private profiles, account cookies, contact details or media files. Use the data lawfully and respect applicable source terms and rights. Source names are used nominatively; this Actor is not affiliated with or endorsed by Bilibili or Apify. Apify's standard terms apply; no custom end-user terms are added.

No AI runs inside the Actor and no scraped data is sent to an AI provider. Apify hosts run datasets/KV/logs and supplies the CN residential proxy; operational platform/proxy costs are company-paid and included in event prices. The public endpoint, request path and public response pass through that proxy. Proxy credentials remain protected and are not output. In-memory rows and ephemeral identities last only for the run. No fixed global dataset, cross-run cache or separate backup is created. Apify storage follows your account's retention policy; delete runs/datasets/KV records in Console or the API when no longer needed.

Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL queries are removed and reports are retained for 30 days. Logs record counts and bounded retry metadata, not scraped titles, creator identities or response bodies. Output intentionally contains the documented public creator identities; do not republish personal data without a lawful basis.

### Troubleshooting and FAQ

**Why did my category return nothing?** It may not appear within the first 200 overall-board positions. Remove the filter as a control. This is not a complete category ranking.

**Why did the run fail with a source response error?** Risk-control or transport failures exhausted the bounded route. Check the run log; do not interpret failed output as a complete snapshot.

**Can I download videos or get all comments?** No. The Actor returns board metadata and count metrics only.

**Does it remember the last run?** No. Compare snapshots downstream using `bvid` and `observedAt`.

**How do I request support?** Open an Actor Store issue with your run link, expected behavior and a non-sensitive reproduction input. Never paste tokens or login cookies. User-reported issues receive a substantive response within 14 calendar days.

### Related Actors

Use [Bilibili Scraper](https://apify.com/automation-lab/bilibili-scraper) for supplied-video details and keyword search. This Actor instead discovers the current overall popular board.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/bilibili-popular-category-videos/changelog.md

# Actor input Schema

## `maxResults` (type: `integer`):

Global maximum unique matching video rows per run, default 50, from 1 to 200. Scans at most the first 200 current overall-board positions, stopping sooner at this limit or source exhaustion. Filters and duplicates can yield fewer rows; zero is not unlimited.

## `categoryIds` (type: `array`):

Optional positive numeric Bilibili category IDs, matched by exact equality with categoryId using ANY semantics. Empty or omitted means all categories. Applied locally within the first 200 overall popular-board positions; no complete category-ranking claim. Example: 21 is 日常 (daily life); inspect output categoryId/categoryName for other IDs. May legitimately return zero rows.

## Actor input object example

```json
{
  "maxResults": 20,
  "categoryIds": []
}
```

# Actor output Schema

## `dataset` (type: `string`):

Unique matching videos from the bounded overall popular board.

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

Saved count, filters and scanning cap.

# 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 = {
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/bilibili-popular-category-videos").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 = { "maxResults": 20 }

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/bilibili-popular-category-videos").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 '{
  "maxResults": 20
}' |
apify call automation-lab/bilibili-popular-category-videos --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/bilibili-popular-category-videos"
        }
    }
}
```

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/eRDAaLWk2zCVxbsKb/builds/mknqcHY4xn74Rsf18/openapi.json
