# Bilibili Scraper (B站 哔哩哔哩) - Videos, Comments, Danmaku (`alom/bilibili-scraper`) Actor

Scrape Bilibili (B站 / 哔哩哔哩) without login or cookies: video search beyond the 1,000-result cap, video details, creator videos and profiles, popular feed, full comment threads with replies, danmaku (弹幕) analytics. From $2 per 1,000 results.

- **URL**: https://apify.com/alom/bilibili-scraper.md
- **Developed by:** [Alom Dev](https://apify.com/alom) (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 $2.00 / 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

## Bilibili Scraper (B站 / 哔哩哔哩)

Scrape **Bilibili**, China's largest video platform for Gen-Z (300M+ monthly users), into JSON, CSV or Excel:
**search videos by keyword (past Bilibili's 1,000-result cap), video details, a creator's uploads and profile, the
popular/trending feed, comments with full reply threads, and danmaku (弹幕) reaction profiles**. You get views, likes, coins, favorites, shares, danmaku and comment counts, tags, category, and author.

✅ **No login, no cookies, no browser:** pure HTTP, so runs are fast and cheap.
✅ **Much cheaper than the alternatives**, and platform usage (compute and proxy) is included.
✅ **Drop-in compatible** with the most-used Bilibili scraper's input and output field names.
✅ **Monitoring mode:** return only videos you haven't seen yet, on a schedule.
✅ **Danmaku profiles:** per-video reaction rate, peak minute, unique senders and a timeline sample.
✅ **Deep search:** thousands of videos per keyword, not just the first ~1,000.

### What can you use Bilibili data for?

- **Brand & market research in China:** how Gen-Z talks about your brand, product or game.
- **Creator (KOL/UP主) discovery and vetting:** followers, total likes, upload frequency, per-video engagement.
- **Trend monitoring:** what's popular right now, per category, every hour or day.
- **Gaming & entertainment:** Chinese reception of launches, trailers, anime and film.
- **AI & research datasets:** Chinese-language titles, descriptions, tags and comments.

### Switching from another Bilibili scraper?

1. Keep your input. `mode`, `searchQuery`, `sortOrder`, `durationFilter`, `pubtimeBegin`/`pubtimeEnd`, `videoUrls`,
   `userIds`, `category`, `maxResults`, `includeComments`, `maxComments`, `sortComments`, `deltaMode` and
   `monitorName` work the same way.
2. Change the Actor ID to `alom/bilibili-scraper`.
3. Output rows use the same field names (`bvid`, `viewCount`, `likeCount`, `coinCount`, `authorMid`, `type`, …),
   so your pipeline keeps working.

**What it costs:** 10,000 videos cost **$40 on the Free plan and $20 on Business** here, compared with about
**$200** at the $20 per 1,000 that some Bilibili scrapers charge. Platform usage is included.

### Modes

| Mode | Input | Output |
|---|---|---|
| `search` | keyword(s), sort, length, date range | videos (up to 5,000 per keyword, see Deep search) |
| `video_detail` | video URLs / BV / av ids / b23.tv links | full stats incl. **coins and shares**, plus tags |
| `video_comments` | video URLs / BV ids / b23.tv links | comments, 20 per page, plus full reply threads |
| `user_videos` | creator ids, space URLs or b23.tv links | one creator profile row + their videos, newest first |
| `user_profile` | creator ids, space URLs or b23.tv links | followers, following, total likes, videos, level, verification |
| `popular` | optional category | the trending feed, with full stats |

### Output example

```json
{
    "type": "video",
    "bvid": "BV1LraH6qEr5",
    "aid": 117353874593121,
    "title": "【原神】免费新5星命座！7.2卡池官宣！…",
    "url": "https://www.bilibili.com/video/BV1LraH6qEr5",
    "duration": 140,
    "durationFormatted": "2:20",
    "viewCount": 7595,
    "likeCount": 3945,
    "coinCount": 115,
    "favoriteCount": 55,
    "shareCount": 7,
    "danmakuCount": 108,
    "replyCount": 44,
    "authorName": "游戏大猪猪",
    "authorMid": 574115689,
    "publishDate": "2026-09-29T03:15:55.000Z",
    "category": "手机游戏",
    "tags": ["原神", "手机游戏"],
    "scrapedAt": "2026-09-29T10:00:00.000Z"
}
```

Creator rows (`type: "user"`) include `fans`, `attention`, `archiveCount`, `likeCount`, `level`, `isOfficial`,
`officialDesc`. Comment rows (`type: "comment"`) include `text`, `likeCount`, `replyCount`, `authorName`,
`authorLevel`, `createdAt`, `videoBvid`, and for replies `isThreadReply` + `rootRpid` (the comment they answer).

### Danmaku profiles (弹幕)

Danmaku are Bilibili's on-screen comments, each tied to a second of the video. Turn on **`includeDanmaku`** and
every video also gets one `type: "danmaku"` row:

| Field | Meaning |
|---|---|
| `danmakuFetched` | danmaku in the pool Bilibili keeps for the video (capped: e.g. 3,600 kept of 128,575) |
| `danmakuTotal` / `danmakuPoolCapped` | the video's own count (single-part videos; `null` for multi-part) and whether the pool is smaller |
| `danmakuUniqueSenders` | distinct senders |
| `danmakuPerMinute`, `danmakuRateBasisSecs` | reaction rate and the duration it was computed over |
| `danmakuPeakMinute`, `danmakuPeakMinuteCount` | the minute the audience reacted to most |
| `danmakuByMinute` | danmaku per minute of the video (a histogram) |
| `danmakuFirstAt` / `danmakuLastAt` | first and last position, in seconds |
| `danmakuSample` / `danmakuSampleAt` | `danmakuSampleSize` texts (default 25, 0-500) spread evenly over the video, with their positions |

```json
{ "type": "danmaku", "bvid": "BV1LraH6qEr5", "danmakuFetched": 273, "danmakuTotal": 355, "danmakuPoolCapped": true,
  "danmakuUniqueSenders": 246, "danmakuPerMinute": 117, "danmakuPeakMinute": 0, "danmakuPeakMinuteCount": 125,
  "danmakuByMinute": [125, 117, 31], "danmakuSample": ["跳过等女皇！", "胡桃胡桃胡桃胡桃胡桃", "…"] }
```

A profile is **one row per video**, billed as its own `danmaku-profile` event (see pricing). Videos with no danmaku,
or whose danmaku could not be fetched, get no profile row and are not charged for one. Works in `search`,
`video_detail`, `user_videos` and `popular`.

### Deep search (past 1,000 results)

Bilibili stops one search at ~1,000 videos. When you set **Max results** above that, the search continues on its own:
it asks for the same keyword again, one date window at a time (newest first), each window starting at the oldest
video the previous one returned. Duplicates are never returned or charged twice, and videos outside the requested
dates are dropped. It stops at the first of: your Max results, your charge limit, the run timeout, or 25 windows per
keyword. The log (and the `SEARCH_COVERAGE` record in the run's key-value store) states the published-date span it
covered and what stopped it. In monitoring mode (`deltaMode`) deep search is off.

Values a given Bilibili endpoint doesn't provide are `null`, never a made-up `0`. For example, search results don't
include coins or shares; use `video_detail` for those.

### How much does it cost?

**From $2 per 1,000 results.** One result = one video, one comment, or one creator profile.

| Apify plan | Price per 1,000 results |
|---|---|
| Free | $4.00 |
| Starter (Bronze) | $3.00 |
| Scale (Silver) | $2.50 |
| Business (Gold) and above | $2.00 |

- 500 search results: **$2.00** on the Free plan, **$1.00** on Business
- 50 creators' profiles: **$0.20** on the Free plan

You only pay for results you get. Platform usage is included.

**Danmaku profiles** (only with `includeDanmaku` on) cost **$0.02 per profiled video** (a separate `danmaku-profile`
event), on top of the normal result price for that row. Each profile downloads and analyses the video's whole danmaku
pool, so it is priced separately. Leave it off and you never pay for it.

### Monitoring (only new videos)

Turn on **"Only new videos since my last run"**, give it a name (e.g. `nike-weekly`), and schedule the run in Apify
Console. Each run returns only videos no earlier run with that name returned. It works in `search` (use
`sortOrder: "pubdate"`), `popular` and `user_videos`.

```json
{ "mode": "search", "searchQuery": "耐克", "sortOrder": "pubdate", "maxResults": 200, "deltaMode": true, "monitorName": "nike-weekly" }
```

### Your own login (optional, at your own risk)

You don't need a Bilibili account: comments page 20 at a time and reply threads load in full without login. If
you still want to, paste the `SESSDATA` cookie value of **your own** account in **"Your own Bilibili SESSDATA
cookie"**. It's checked once and then sent **only with comment and reply requests**. Apify stores it encrypted, and
it never appears in logs or output. ⚠️ **This is your account and your risk:** Bilibili can rate-limit or restrict
accounts that make automated requests. An expired or wrong value is ignored, the log says so, and the run carries on
without login. Leave the field empty to not use it.

### Limitations

- **Comments:** up to 1,000 per video (`maxComments`), replies included. Videos with comments closed return none.
- **Danmaku:** Bilibili keeps a capped pool per video. On busy videos the profile describes that pool, not every
  danmaku ever sent (`danmakuPoolCapped: true`). Multi-part videos are profiled on their first part.
- **Deep search** moves back one second at a time. If more than one window's worth of videos (~1,000) share the same
  publish second, it stops and says so.
- **Creator video lists include the view count only.** For full stats, pass the video URLs to `video_detail`.
- An invalid or expired input (e.g. a dead `b23.tv` link) is reported by name as "not found". The other inputs still
  run.

### FAQ

**Do I need a Bilibili account?** No.

**Does it work outside China?** Yes. It runs on Apify's servers; nothing to configure.

**Is it legal?** It collects publicly visible data. You are responsible for how you use it, including data
protection rules for any personal data (usernames, comments).

### More scrapers from the same developer

- [Google Trends API & Scraper](https://apify.com/alom/google-trends-scraper): interest over time, regions, related queries and Trending Now, a pytrends alternative
- [YouTube Scraper](https://apify.com/alom/youtube-scraper): videos, channels, Shorts, comments, subtitles and community posts without the API quota
- [Threads Scraper](https://apify.com/alom/threads-scraper): posts, profiles, replies and keyword search on Meta Threads, no login
- [Google Hotels Scraper](https://apify.com/alom/google-hotels-scraper): hotel prices from every booking site across dates, room rates and reviews
- [Google Ads Transparency Scraper](https://apify.com/alom/google-ads-transparency-scraper): every Google ad a competitor runs, with the real ad copy
- [Threads Account Finder](https://apify.com/alom/threads-lead-finder): Threads accounts by keyword with followers, bio links and the contacts they list
- [Threads Hashtag & Keyword Monitor](https://apify.com/alom/threads-keyword-monitor): only the new posts for your keywords and #hashtags, for scheduled runs

### Feedback

Missing a field, found a bug, or need a feature? Open an issue in the **Issues** tab and I'll take a look. If this
Actor saved you time, a short review on the Store page helps other people find it.

# Actor input Schema

## `mode` (type: `string`):

Pick one mode. Each mode uses the matching field below.

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

Keyword for <b>search</b> mode, in Chinese or English (e.g. <code>人工智能</code>, <code>minecraft</code>).

## `searchQueries` (type: `array`):

Optional: several keywords in one run. Each keyword gets up to <b>Max results</b> videos.

## `sortOrder` (type: `string`):

Search result order.

## `durationFilter` (type: `string`):

Search only.

## `pubtimeBegin` (type: `string`):

Search only: videos published on or after this date (China time).

## `pubtimeEnd` (type: `string`):

Search only: videos published on or before this date (China time).

## `videoUrls` (type: `array`):

For <b>video details</b> and <b>video comments</b>: full URLs, <code>BV...</code> ids, <code>av...</code> ids or <code>b23.tv</code> short links.

## `userIds` (type: `array`):

For <b>creator videos</b> and <b>creator profiles</b>: e.g. <code>546195</code>, <code>https://space.bilibili.com/546195</code> or a <code>b23.tv</code> short link to a creator's space.

## `category` (type: `string`):

For <b>popular</b> mode: keep only this category.

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

Maximum videos per keyword, per creator, or for the popular feed. Bilibili caps one search at ~1,000 videos; above that, search automatically continues through date windows (newest first) until this number is reached.

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

Also return each video's comments as rows (<code>type: comment</code>), 20 per page in Bilibili's own order, up to <b>Max comments per video</b>. No login needed. Each comment is one result, so this multiplies the rows (and the cost) of a run: cap it with <b>Max comments per video</b>.

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

Also return the replies under each comment, one row each, tagged with <code>rootRpid</code> / <code>isThreadReply</code>. When a comment has more replies than Bilibili previews, the whole thread is paged (20 per request) until <b>Max comments per video</b> is reached. Replies are billed as normal comment rows.

## `maxComments` (type: `integer`):

Upper limit per video, counting comments and replies together.

## `sortComments` (type: `string`):

Which comments to prefer.

## `includeTags` (type: `boolean`):

Video details mode: one extra request per video for its tags.

## `includeDanmaku` (type: `boolean`):

One extra row per video (<code>type: danmaku</code>) that reduces the video's on-screen comments to reaction metrics: danmaku fetched vs the video's total, unique senders, danmaku per minute, the <b>peak minute</b> and its count, a per-minute histogram, first/last positions, and a text sample spread evenly across the timeline. Bilibili keeps a capped pool of danmaku per video (e.g. 3,600 of 128,575), and the row says so (<code>danmakuPoolCapped</code>). <b>Billed as a separate danmaku-profile event</b> (see Pricing); off by default. Works in search, video details, creator videos and popular modes.

## `danmakuSampleSize` (type: `integer`):

How many danmaku texts to include in each profile row, spread evenly across the video. 0 = metrics only. The sample stays inside the one row, so it does not add rows or cost.

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

Skip videos an earlier run with the same state key already returned. Works in search, popular and creator-videos modes. Pair with a Schedule.

## `monitorName` (type: `string`):

Keep separate memories for different monitors (e.g. <code>nike-weekly</code>). Defaults to <code>default</code>.

## `sessdataCookie` (type: `string`):

<b>Not needed for normal use</b>: comments and reply threads already work without login. If you paste the value of the <code>SESSDATA</code> cookie of <b>your own</b> Bilibili account, it is checked once and then sent <b>only with comment and reply requests</b>, as a logged-in visitor would. It is stored encrypted and never logged or returned. <b>Use at your own risk</b>: automated requests from a logged-in account can get that account rate-limited or restricted by Bilibili. An expired or wrong value is ignored (the run says so) and comments are fetched without login. Leave empty to not use it.

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

Parallel requests for video/creator lists.

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

Default Apify datacenter proxy works well and is included in the price.

## Actor input object example

```json
{
  "mode": "search",
  "searchQuery": "原神",
  "sortOrder": "totalrank",
  "durationFilter": "any",
  "videoUrls": [
    "https://www.bilibili.com/video/BV1LraH6qEr5"
  ],
  "category": "all",
  "maxResults": 50,
  "includeComments": false,
  "includeReplies": false,
  "maxComments": 20,
  "sortComments": "hot",
  "includeTags": true,
  "includeDanmaku": false,
  "danmakuSampleSize": 25,
  "deltaMode": false,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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 = {
    "searchQuery": "原神",
    "videoUrls": [
        "https://www.bilibili.com/video/BV1LraH6qEr5"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("alom/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 = {
    "searchQuery": "原神",
    "videoUrls": ["https://www.bilibili.com/video/BV1LraH6qEr5"],
}

# Run the Actor and wait for it to finish
run = client.actor("alom/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 '{
  "searchQuery": "原神",
  "videoUrls": [
    "https://www.bilibili.com/video/BV1LraH6qEr5"
  ]
}' |
apify call alom/bilibili-scraper --silent --output-dataset

```

## MCP server setup

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