# Bilibili Scraper - Videos, Rankings, Uploaders & Comments (`dami_studio/bilibili-scraper`) Actor

Bilibili videos with plays, likes, coins, favourites, shares, danmaku and comment counts, tags and sub-zone, from the popular list, a leaderboard, a sub-zone's top videos by date, uploaders or links. Comments on any video too. No account or login.

- **URL**: https://apify.com/dami\_studio/bilibili-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Social media, Videos
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.95 / 1,000 video returneds

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

## Bilibili Scraper

Bilibili videos as rows: title, uploader, plays, likes, coins, favourites, shares, danmaku and comment counts, length, publish time, tags, sub-zone, cover and link. Chinese text comes back exactly as Bilibili shows it.

You pick where the videos come from:

- **Popular right now** (热门), the list on Bilibili's popular page, about 650 videos deep.
- **Leaderboard** (排行榜), the top 100 of the last few days, for the whole site or one of 19 zones.
- **Top videos in a sub-zone**, such as 单机游戏, published between two dates up to 90 days apart and sorted by plays, coins, favourites, danmaku or comments.
- **Uploaders' videos** (UP主), newest, most played or most favourited first.
- **Videos you already have**, as links, BV IDs or av numbers.

Or pick **Comments** and give it videos.

There's no Bilibili account, cookie or key to set up. The actor reads the same public data Bilibili's site shows a visitor who isn't signed in.

### What it doesn't do

- **No keyword search across all of Bilibili.** A keyword works only inside a sub-zone's top list, where Bilibili returns one list of up to 100 videos.
- **Comments stop where a signed-out visitor stops.** Bilibili doesn't always show the full comment list to someone who isn't signed in, and this actor never signs in. When the full list isn't open, the run returns the top comments and says so in its status.
- **Leaderboards have no week or month view.** Bilibili's leaderboard always covers the last few days. For a longer stretch, use Top videos in a sub-zone with your own dates.
- **No danmaku text, subtitles or video files.** Danmaku comes back as a count.
- **Counts keep moving.** Every row carries `scrapedAt`, the moment its numbers were read.

### Input

**What to get** decides what the run does. Fill in the fields for that choice; the rest are ignored.

**Popular right now.** Only **Maximum videos** matters. Rows come back in the order Bilibili lists them.

**Leaderboard.** Pick a **Leaderboard zone**, or leave it on the whole site. A leaderboard holds 100 videos. Anime series (番剧) lists only a handful.

**Top videos in a sub-zone.** Pick a **Sub-zone** and an **Order by**, and set **Published from** and **Published to**. The range can be up to 90 days; leave both dates empty for the last 7 days. An optional **Keyword** narrows the list to videos Bilibili matches to that word.

**Uploaders' videos.** Paste space links like `https://space.bilibili.com/2929048` or bare UIDs into **Uploaders**, choose an **Uploader order**, and set **Maximum videos per uploader**. Sorted newest first, the dates work too: the run skips videos newer than Published to and stops at the first one older than Published from. A video made together with other uploaders (联合投稿) shows up on each of their pages, and so in each of their lists here; its uploader fields name the lead uploader, and `listedUnder` says whose list it came from.

**Videos from links or IDs.** Paste links, BV IDs, av numbers or b23.tv short links into **Videos**. One run takes up to 1,000.

**Comments.** Paste videos into **Videos** (up to 200), set **Maximum comments per video**, and turn on **Include replies** if you want the replies under each comment as rows of their own. Comments come back with the top ones first.

**Add tags** is on unless you turn it off. Tags come from a separate lookup for each video, and Bilibili only answers so many of those in a row. On a run of more than a hundred or so videos, some rows can come back with `tags` empty; the status says how many. If you don't need tags, turn this off and the run finishes sooner.

Dates are Beijing dates, because that's where Bilibili's day starts and ends.

```json
{
  "source": "categoryTop",
  "subZone": "17",
  "topBy": "coin",
  "publishedFrom": "2026-09-06",
  "publishedTo": "2026-09-12",
  "maxVideos": 200
}
```

### Output

One row per video, in the order its list gives them.

| Field | Example | Notes |
|---|---|---|
| `source` | `popular` | where the row came from: `popular`, `ranking`, `categoryTop`, `uploader` or `video` |
| `rank` | `1` | its place in that list; empty for videos you pasted |
| `bvid` | `BV1WQYd6DEgs` | |
| `aid` | `117259670392443` | the av number, as text |
| `url` | `https://www.bilibili.com/video/BV1WQYd6DEgs` | |
| `title` | `《魔兽世界》：“无限”宣传动画 《崭新的天地》` | |
| `description` | `重启艾泽拉斯，冒险永无止境！…` | |
| `coverUrl` | `https://i0.hdslb.com/bfs/archive/79b8b51898b2b5aafed0781916375206430a9d06.jpg` | |
| `duration` | `3:51` | also as `durationSeconds`: `231` |
| `publishedAt` | `2026-09-12T19:20:07.000Z` | UTC |
| `uploaderId` | `2929048` | as text: some run to 16 digits |
| `uploaderName` | `魔兽世界` | |
| `uploaderUrl` | `https://space.bilibili.com/2929048` | |
| `views` | `2852156` | plays |
| `likes` | `22544` | |
| `coins` | `21715` | 投币 |
| `favourites` | `12515` | 收藏 |
| `shares` | `15239` | |
| `danmaku` | `2321` | the number of bullet comments |
| `comments` | `4367` | |
| `tags` | `["魔兽世界", "魔兽", "暴雪游戏", "游戏CG", "宣传片", "MMORPG"]` | empty when Add tags is off, or when Bilibili didn't answer that video's lookup |
| `category` | `网络游戏` | the sub-zone |
| `categoryId` | `65` | |
| `listedUnder` | `2929048` | for uploaders' videos: whose list the row came from; empty otherwise |
| `scrapedAt` | `2026-09-13T14:30:55.389Z` | when these numbers were read |

A **Comments** run gives one row per comment instead: `videoBvid`, `videoAid`, `videoTitle`, `videoUrl`, `commentId`, `text`, `authorName`, `authorId`, `likes`, `replyCount`, `postedAt`, `isReply` and, for a reply, `replyTo` (the comment it answers).

The run also leaves `RUN_REPORT` in its key-value store: what it was asked for, what each list returned, what was skipped and why, anything that couldn't be read, and why the run stopped.

### What you pay

Each video row is one charge, and so is each comment row. Nothing else costs anything: not the sample row a run with nothing picked returns, not a video that's deleted or hidden, not a list that couldn't be read, not a row skipped because it didn't match what you asked for, and not a repeat. If you set a maximum charge for the run, it stops when that's reached, and every row you get has been paid for. The price is on the Pricing tab.

### Limits

- 5,000 videos per run, 100 uploaders, 1,000 pasted videos, and comments on 200 videos at up to 2,000 each.
- A sub-zone's top list covers up to 90 days of publish dates.
- If Bilibili stops answering for a while, the run waits a minute and carries on, up to three times. Whatever still can't be read is named in the status and isn't charged.

### Questions

**Why don't my numbers match the site exactly?** Plays and likes change by the minute, and each row holds them as they were when `scrapedAt` says.

**Can I watch a video's numbers over time?** Yes. Schedule the actor with the same Videos list and compare the rows between runs.

**What's the difference between the leaderboard and a sub-zone's top list?** The leaderboard is Bilibili's own ranking of the last few days, and it mixes in things like how recent a video is. A sub-zone's top list is plain arithmetic: every video published in your dates, sorted by the number you picked.

**Why is a video I pasted missing?** The status says. Usually it's been deleted, hidden, or is still under review, and nothing is charged for it.

# Actor input Schema

## `source` (type: `string`):

Each run does one of these. A run with nothing picked returns one sample row and charges nothing.

## `maxVideos` (type: `integer`):

The most video rows one run returns, for every choice except Comments. The popular list holds about 650 videos and a leaderboard 100. Each video returned is one charge.

## `rankingZone` (type: `string`):

For Leaderboard. Bilibili ranks the last few days' videos and shows the top 100, for the whole site or one zone. Anime series (番剧) lists only a handful.

## `subZone` (type: `string`):

For Top videos in a sub-zone. Every Bilibili video is filed under one sub-zone, such as 单机游戏 (single-player games) under Gaming.

## `topBy` (type: `string`):

For Top videos in a sub-zone.

## `keyword` (type: `string`):

Optional, for Top videos in a sub-zone: only videos Bilibili matches to this word. With a keyword Bilibili returns one list of up to 100.

## `publishedFrom` (type: `string`):

For Top videos in a sub-zone, where the range can be up to 90 days and defaults to the last 7, and for uploaders sorted newest first. Beijing dates, written like 2026-09-01.

## `publishedTo` (type: `string`):

The last publish day, Beijing time. Leave it empty to go up to today.

## `uploaders` (type: `array`):

For Uploaders' videos. A space link such as https://space.bilibili.com/2929048, or the numeric UID.

## `uploaderSort` (type: `string`):

For Uploaders' videos.

## `maxPerUploader` (type: `integer`):

For Uploaders' videos. Maximum videos still caps the whole run.

## `videos` (type: `array`):

For Videos from links or IDs, and for Comments (up to 200 videos there). Links like https://www.bilibili.com/video/BV1WQYd6DEgs, BV IDs, av numbers, or b23.tv short links.

## `maxCommentsPerVideo` (type: `integer`):

For Comments. Each comment returned is one charge.

## `includeReplies` (type: `boolean`):

For Comments: also return the replies under each comment, as rows of their own. They count toward Maximum comments per video.

## `addTags` (type: `boolean`):

Tags take one extra lookup per video, and on a big run Bilibili can leave some of those unanswered; the status says how many. Turn this off for faster runs, and each video's tags come back empty.

## Actor input object example

```json
{
  "source": "popular",
  "maxVideos": 20,
  "rankingZone": "0",
  "topBy": "click",
  "uploaderSort": "newest",
  "maxPerUploader": 30,
  "maxCommentsPerVideo": 100,
  "includeReplies": false,
  "addTags": true
}
```

# Actor output Schema

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

One row per video, or one per comment when you picked Comments. Video rows carry the title, uploader, plays, likes, coins, favourites, shares, danmaku and comment counts, length, publish time, tags, sub-zone, cover and link.

## `report` (type: `string`):

What the run was asked for, how many rows came back from each list, what was skipped and why, and why the run stopped.

# 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 = {
    "source": "popular",
    "maxVideos": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/bilibili-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 = {
    "source": "popular",
    "maxVideos": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/bilibili-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 '{
  "source": "popular",
  "maxVideos": 20
}' |
apify call dami_studio/bilibili-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/bilibili-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/gdEJfmBBgVJOB44MG/builds/nKCIcjZKwVRYhY3BB/openapi.json
