# Bilibili Scraper — Video, UP主, Comments & Search (`sian.agency/bilibili-video-scraper`) Actor

Bilibili scraper for video data, UP主 profiles, comments, danmaku (bullet chats), AI subtitle metadata & keyword search. KOL discovery, view/like/coin/favorite counts, creator analytics for China market research. Eight operations, one clean dataset per run. No API key.

- **URL**: https://apify.com/sian.agency/bilibili-video-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Social media, Videos
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 video danmakus

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Video Scraper — Videos, UP主, Comments, Danmaku & AI Subtitles 🚀

[![SIÁN Agency Store](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![SIÁN Taobao & Tmall](https://img.shields.io/badge/SI%C3%81N-Taobao%20%26%20Tmall-FF4F00)](https://apify.com/sian.agency/taobao-tmall-product-scraper?fpr=sian) [![SIÁN Kwai & Kuaishou](https://img.shields.io/badge/SI%C3%81N-Kwai%20%26%20Kuaishou-FF4906)](https://apify.com/sian.agency/kwai-kuaishou-scraper?fpr=sian) [![SIÁN Douyin](https://img.shields.io/badge/SI%C3%81N-Douyin-161823)](https://apify.com/sian.agency/douyin-scraper?fpr=sian)

#### 🎉 Eight scrapers in one — video data, UP主 profiles, follower stats, comments, danmaku (bullet chats), AI subtitle URLs & keyword search on Bilibili (B站)
##### Built for China-market researchers, KOL agencies, gaming/anime/tech analysts, and AI training-data teams who need clean Bilibili datasets without scraping the player UI

---

### 📋 Overview

**Scrape Bilibili (B站) into clean structured datasets — without an account, an API key, or a single Python script.** This Bilibili scraper turns China's leading long-form video platform for gaming, anime, tech and youth culture into a JSON / CSV / Excel feed your team can query, monitor, and pipe into BI.

**Why thousands of China-market professionals choose us:**
- ✅ **8 operations in one actor**: video detail, UP主 profile, follower stats, user video catalog, comments, danmaku, AI subtitle URLs, keyword search — pick what you need per run
- ⚡ **BigInt-safe IDs** — Bilibili `aid` / `cid` / `rpid` IDs routinely exceed 16 digits and break naive JSON parsers. We parse them with `json-bigint` so every ID survives the round-trip as a clean string. No silent precision loss.
- 🎯 **Danmaku (bullet chat) extraction** — pull Bilibili's signature overlay comments (弹幕) with timestamps, text, mode, color, font size, and user hash. The only Bilibili actor on Apify exposing this dataset.
- 💰 **Best price on the market**: pay-per-result, no subscriptions. Headline `searchVideo` runs at $0.004 per row at BRONZE — cheaper than building it in-house.
- 💎 **AI subtitle URLs for ML pipelines** — fetch Bilibili's auto-generated `ai-zh` / `ai-en` subtitle JSON URLs for any video. Feed them directly into translation, summarization, or video-search pipelines without scraping the player.
- ✨ **NEW**: silent backup data source — if the primary feed hiccups, we transparently failover so your runs don't break

---

### ✨ Features

- 📺 **Video Detail** — full BV-ID lookup: title, description, view/like/coin/favorite/share/comment counts, cover, creator, tags, multi-part `videoPages[]`
- 👤 **User Profile** — UP主 deep-dive: bio, level, VIP status, official verification, live room, school, profession, join date
- 📈 **User Relation Stat** — fast follower / following / whisper counts when you don't need the full profile (cheaper)
- 🎞️ **User Videos** — paginated complete video catalog for any UP主 (~30 videos/page)
- 💬 **Video Comments** — paginated comments with reply samples, reviewer level, VIP status, and like counts
- 🎯 **Video Danmaku (弹幕)** — bullet-chat overlay text + timestamps for any video — unique on the Apify store
- 🌐 **Video Caption Metadata** — language list + signed subtitle URLs (including AI-generated `ai-zh` / `ai-en`)
- 🔍 **Search Videos** — paginated keyword search (~20 results/page, up to 50 pages = 1,000 videos per run)
- 🔁 **Silent backup source** — automatic failover if the primary feed is throttled or unavailable
- 📊 **Built-in HTML run reports** — every run saves a summary with success / error counts and duration
- 🆓 **FREE tier included** — Apify credit lets you test every operation before you commit

---

### 🎬 Quick Start

Pick an operation, provide the required input, hit run. Results land in the default Apify dataset — export to JSON / CSV / Excel in one click.

```bash
curl -X POST "https://api.apify.com/v2/acts/sian.agency~bilibili-video-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"operation":"searchVideo","keyword":"python","maxPages":2}'
````

***

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Pick an Operation

Choose one of `searchVideo`, `videoDetail`, `userDetail`, `userRelationStat`, `userVideos`, `videoComments`, `videoDanmu`, or `videoCaption`. Each operation is built around a single, well-defined job.

#### Step 2: Provide the Required Input

Search needs a `keyword`. Video Detail / Caption need a `bvid`. User operations need a `userId`. Comments need an `aid`. Danmaku needs both `aid` and `cid`. Run `Video Detail` once on any BV ID to harvest its `aid` and `cid` for downstream ops.

#### Step 3: Hit Run, Export Results

Results stream into the default Apify dataset. Filter by `_operation` or `status`, export to JSON / CSV / Excel, or hit the dataset API from your code.

**That's it! In under 60 seconds, you'll have:**

- A clean structured JSON / CSV dataset
- A success-rate HTML run report
- Direct links to every video / creator / comment

***

### 📥 Input Configuration

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `operation` | string | ✅ | One of: `videoDetail`, `userDetail`, `userRelationStat`, `userVideos`, `videoComments`, `videoDanmu`, `videoCaption`, `searchVideo` |
| `bvid` | string | for `videoDetail`, `videoCaption` | Bilibili BV ID (e.g. `BV1rpWjevEip`) from `bilibili.com/video/{BV_ID}` |
| `aid` | string | for `videoComments`, `videoDanmu`, `videoCaption` | Numeric video ID — get it from a Video Detail or Search row |
| `cid` | string | for `videoDanmu`, `videoCaption` | Bilibili chapter ID — one per video part — get it from a Video Detail row |
| `userId` | string | for `userDetail`, `userRelationStat`, `userVideos` | Numeric UP主 ID (`mid`) from `space.bilibili.com/{USER_ID}` |
| `keyword` | string | for `searchVideo` | Search query — Chinese, English, or mixed (Chinese gives best coverage) |
| `maxPages` | integer | ❌ | Max pages for paginated ops (`userVideos`, `videoComments`, `searchVideo`). Default 5. Range 1–50. |

**Examples:**

```json
{ "operation": "searchVideo", "keyword": "python", "maxPages": 3 }
```

```json
{ "operation": "videoDetail", "bvid": "BV1rpWjevEip" }
```

```json
{ "operation": "userDetail", "userId": "3546597933714079" }
```

```json
{ "operation": "videoComments", "aid": "113006243481679", "maxPages": 5 }
```

```json
{ "operation": "videoDanmu", "aid": "113006243481679", "cid": "36010133667" }
```

```json
{ "operation": "videoCaption", "bvid": "BV1rpWjevEip", "aid": "113006243481679", "cid": "36010133667" }
```

***

### 📤 Output

Every run writes rows to the default Apify dataset. Field shape depends on the operation — common fields across all rows include:

| Field | Type | Description |
|-------|------|-------------|
| `_operation` | string | Operation that produced the row |
| `_fetchedAt` | string (ISO) | UTC timestamp when the row was fetched |
| `_page` | integer | Page number for paginated ops |
| `status` | string | `success` or `error` |
| `bvid` | string | Bilibili BV ID |
| `aid` | string | Numeric video ID (BigInt-safe, string-encoded) |
| `videoTitle` | string | Video title (HTML highlight tags stripped) |
| `userId` | string | UP主 numeric ID (`mid`) |
| `userName` | string | UP主 display name |
| `playCount` | integer | View count |
| `likeCount` | integer | Like count |
| `commentCount` | integer | Comment count |
| `favoriteCount` | integer | Favorite count |
| `danmuCount` | integer | Danmaku (bullet-chat) count |
| `coverUrl` | string | Cover image URL (HTTPS-upgraded) |
| `videoPageUrl` | string | Canonical video URL on bilibili.com |
| `userPageUrl` | string | Canonical UP主 space URL |

**Search Videos example row:**

```json
{
  "_operation": "searchVideo",
  "_fetchedAt": "2026-05-14T09:12:08Z",
  "_page": 1,
  "_sourceKeyword": "python",
  "bvid": "BV1rpWjevEip",
  "aid": "113006243481679",
  "videoTitle": "Python 入门 60 分钟速成",
  "videoTitleHighlighted": "<em class=\"keyword\">Python</em> 入门 60 分钟速成",
  "videoDesc": "从零开始的 Python 教程，适合零基础学员...",
  "durationStr": "59:42",
  "publishedAt": 1715812345,
  "playCount": 482103,
  "likeCount": 18244,
  "commentCount": 612,
  "favoriteCount": 9821,
  "danmuCount": 3104,
  "videoTypeName": "校园学习",
  "coverUrl": "https://i0.hdslb.com/bfs/archive/...",
  "videoPageUrl": "https://www.bilibili.com/video/BV1rpWjevEip",
  "userId": "3546597933714079",
  "userName": "TechUP_Lin",
  "avatarUrl": "https://i1.hdslb.com/bfs/face/...",
  "userPageUrl": "https://space.bilibili.com/3546597933714079",
  "status": "success"
}
```

**Video Danmaku example row:**

```json
{
  "_operation": "videoDanmu",
  "_sourceAid": "113006243481679",
  "_sourceCid": "36010133667",
  "danmuId": "1729384756102347901",
  "aid": "113006243481679",
  "cid": "36010133667",
  "danmuText": "前方高能！",
  "timeOffsetSec": 122.84,
  "mode": 1,
  "fontSize": 25,
  "color": 16777215,
  "userHash": "a7c3f2e9",
  "postedAt": 1715900012,
  "status": "success"
}
```

**Video Caption Metadata example row:**

```json
{
  "_operation": "videoCaption",
  "_sourceBvid": "BV1rpWjevEip",
  "_sourceCid": "36010133667",
  "bvid": "BV1rpWjevEip",
  "aid": "113006243481679",
  "cid": "36010133667",
  "languageCode": "ai-zh",
  "languageLabel": "中文（自动生成）",
  "subtitleUrl": "https://aisubtitle.hdslb.com/bfs/ai_subtitle/...",
  "isAiGenerated": true,
  "videoPageUrl": "https://www.bilibili.com/video/BV1rpWjevEip",
  "status": "success"
}
```

> The `subtitleUrl` points to a JSON subtitle file you fetch yourself (Bilibili signs the URL — it expires). One GET request returns the full transcript with per-line timestamps.

***

### 💼 Use Cases & Examples

#### 1. China KOL & UP主 Discovery

**Influencer agencies and brand teams shortlisting Bilibili creators for partnerships.**

**Input:** `searchVideo` on a niche keyword (e.g. `美食`, `数码`, `健身`), then `userDetail` + `userRelationStat` on the top creators
**Output:** Trending UP主 with view counts, follower counts, verification status, school, and bio
**Use:** Build a ranked KOL shortlist filtered by follower band, verification, and engagement — ship the list to your campaign team.

#### 2. Gaming, Anime & Tech Trend Tracking

**Trend analysts monitoring Bilibili's gaming, anime, and developer communities.**

**Input:** `searchVideo` scheduled daily on category keywords + `videoDetail` on the top results
**Output:** Daily snapshot of viral videos with view / like / coin / favorite / comment counts
**Use:** Spot breakout creators and emerging hashtags 1–2 weeks before they hit Douyin or Weibo. Bilibili is the youth-culture leading indicator for China.

#### 3. Comment & Danmaku Sentiment Mining

**Product and brand teams running NLP on Chinese-language fan reactions.**

**Input:** `videoComments` + `videoDanmu` against any BV ID
**Output:** Full review text and live bullet-chat reactions with timestamps
**Use:** Pipe into a Chinese-language sentiment model. Danmaku captures real-time emotional response that comments miss — invaluable for game launches, anime drops, and product reveals.

#### 4. AI Training Data — Subtitles + Danmaku

**ML / AI teams building Chinese-language datasets for translation, summarization, or video search.**

**Input:** `videoCaption` to fetch AI-subtitle URLs + `videoDanmu` for timestamped reactions
**Output:** Signed `ai-zh` / `ai-en` subtitle JSON URLs and bullet-chat overlay text
**Use:** Build a parallel ZH-EN corpus from Bilibili's AI subtitles, or align danmaku timestamps with subtitle segments to train video-aware reaction models.

#### 5. Creator Catalog & Due Diligence

**Brand-safety teams auditing a UP主 before sponsoring.**

**Input:** `userVideos` paginated end-to-end for the candidate's `userId`
**Output:** Complete video catalog with play counts, descriptions, posting cadence, and tags
**Use:** Surface controversial content, posting gaps, and category drift before signing a creator deal.

#### 6. Competitor & Brand Monitoring

**Brand teams tracking how their products are mentioned on Bilibili.**

**Input:** `searchVideo` on brand keywords + `videoComments` on the top videos
**Output:** Daily list of brand-mentioning videos with fan-reaction text
**Use:** Build a real-time brand-mention feed, alert on negative spikes, surface owned-product reviewers for outreach.

#### 7. Cross-Border Market Research

**Consultants producing China-entry briefings for Western brands.**

**Input:** Combine `searchVideo` (category top 100) + `userDetail` (top UP主) + `videoComments` (sentiment)
**Output:** A complete Bilibili category snapshot — top videos, top creators, fan sentiment — in one dataset
**Use:** Drop into a Looker / Tableau dashboard; ship as a stakeholder briefing.

***

### 🔗 Integration Examples

#### JavaScript / Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/bilibili-video-scraper').call({
  operation: 'searchVideo',
  keyword: 'python',
  maxPages: 3,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/bilibili-video-scraper').call(
    run_input={
        'operation': 'searchVideo',
        'keyword': 'python',
        'maxPages': 3,
    }
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~bilibili-video-scraper/runs?token=YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"operation":"searchVideo","keyword":"python","maxPages":3}'
```

#### Automation Workflows (N8N / Zapier / Make)

1. **Trigger**: Cron / webhook
2. **HTTP Request**: Call the actor API with `operation` + required field
3. **Process**: Filter the JSON dataset by `status === "success"`
4. **Action**: Push to Google Sheets, Slack, your data warehouse, or your ML training pipeline

***

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- Apify FREE accounts include a monthly credit allowance you can spend on any actor
- Full feature access — same quality as PAID
- Test every operation before you commit a cent
- No credit card required

#### PAID Tier (Production Ready)

- Pay-per-result: charged for successful rows, never for errors
- No subscriptions, no minimums, no surprises
- Bulk-friendly tiers — BRONZE → SILVER → GOLD → PLATINUM → DIAMOND volume discounts

💰 **Best price on the market** — headline `searchVideo` runs at $0.004 per row at BRONZE, with steeper discounts at higher tiers. Danmaku is $0.002 per row.

🔗 [View live pricing](https://apify.com/sian.agency/bilibili-video-scraper?fpr=sian)

***

### ❓ Frequently Asked Questions

**Q: What is danmaku (弹幕) and why does it matter?**
A: Danmaku are bullet-chat comments that fly across the video as it plays — a signature Bilibili feature. They capture real-time emotional reactions (jokes, hype, criticism) that regular comments miss. Bilibili's gaming, anime, and tech audiences live in danmaku. Our `videoDanmu` operation is the only one on the Apify store that exposes this data cleanly.

**Q: Do I need a Bilibili account or API key?**
A: No. The actor is fully managed — no account, no key, no setup. Just pick an operation and run.

**Q: Why are video IDs returned as strings, not numbers?**
A: Bilibili's `aid`, `cid`, `rpid`, and `dmid` IDs routinely exceed `Number.MAX_SAFE_INTEGER` (16+ digits). Storing them as JavaScript numbers silently corrupts the last few digits. We parse with `json-bigint` and return every ID as a string so it survives JSON round-trips and database inserts safely.

**Q: How do I get the `aid` and `cid` for a video?**
A: Run `videoDetail` once on any BV ID — the response includes `aid`, `cid`, and `videoPages[].cid` for multi-part videos. Then feed those into Comments, Danmaku, or Caption operations.

**Q: What does the Caption operation return — the transcript text?**
A: It returns subtitle **metadata + signed URLs**, not the transcript text. Each row gives you a `subtitleUrl` that points to a JSON subtitle file. One GET request to that URL returns the full transcript with per-line timestamps. We don't fetch the file for you because subtitle JSON shapes vary by language and you'll want to handle them in your own pipeline.

**Q: Does it support Chinese keywords?**
A: Yes. Chinese keywords give the best results (e.g. `游戏`, `美食`, `编程`). English and mixed queries also work but coverage is thinner on native content.

**Q: How many results per page?**
A: `searchVideo` ~20/page (cap 50 pages = 1,000 videos), `userVideos` ~30/page, `videoComments` ~20/page with sub-reply samples. `videoDetail` / `userDetail` / `userRelationStat` / `videoDanmu` / `videoCaption` are single-row or single-payload operations.

**Q: What output formats are available?**
A: JSON, CSV, Excel, and HTML — export directly from the Apify dataset, or hit the dataset API from your code.

**Q: How fresh is the data?**
A: Live — every run hits Bilibili in real time. No caching, no stale data.

**Q: Is this legal?**
A: We only extract publicly available data. See the [Legal](#-is-it-legal-to-scrape-data) section below for full guidance on GDPR + personal-data considerations.

***

### 🐛 Troubleshooting

**"Missing required input"**

- `searchVideo` needs `keyword`. `videoDetail` / `videoCaption` need `bvid`. `videoComments` needs `aid`. `videoDanmu` / `videoCaption` need `aid` + `cid`. User operations need `userId`.

**"Video not found — it may have been removed"**

- The BV ID exists but Bilibili has removed or restricted the video. Try a fresh ID from a `searchVideo` run.

**"No captions available for this video"**

- Not every Bilibili video has AI-generated subtitles. Older videos, music videos, and very short clips often lack them. Try a longer educational or commentary video.

**Run returns 0 rows on `searchVideo`**

- Keyword may be too narrow or in the wrong language. Try a Chinese keyword (e.g. `游戏` instead of `gaming`).

**"Data source temporarily unavailable — please retry"**

- The upstream feed is briefly throttled. Our retry-with-backoff logic handles this automatically — just re-run if a small fraction of pages fail.

**Big numeric IDs look like strings in the dataset**

- That's intentional — Bilibili's `aid` / `cid` / `rpid` / `dmid` are too large for JavaScript numbers. We return them as strings to preserve precision.

***

### ⚠️ Trademark Disclaimer

This is an **independent scraping tool**. It is not affiliated with, endorsed by, or sponsored by Shanghai Bilibili Technology Co., Ltd. The **Bilibili®** and **B站** names appear under nominative fair use solely to identify the public data source this tool helps you collect.

All product names, logos, and brands belonging to Bilibili are property of their respective owners.

***

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

***

### 🤝 Support

[![Telegram Support](https://img.shields.io/badge/Telegram-Support%20Group-0088cc?logo=telegram)](https://t.me/+vyh1sRE08sAxMGRi)

**Join our active support community**

- For issues or questions, open an issue in the actor's Apify Console → Issues tab
- Check the [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <apify@sian-agency.online>

⭐ **Loving this actor?** Leave us a [5-star review](https://apify.com/sian.agency/bilibili-video-scraper/reviews) — it helps us build more features for you.

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Actor input Schema

## `operation` (type: `string`):

🎯 **PICK ONE OPERATION PER RUN.** Each run produces one clean dataset matching the chosen mode.

- **📺 Video Detail** — deep scrape of a single Bilibili video by BV ID (title, description, view/like/coin/favorite/share/comment counts, cover, creator, video parts, tags)
- **👤 User Profile** — full Bilibili UP主 profile by user ID (bio, level, verification, VIP status, live room, school, profession, join date)
- **📈 User Relation Stat** — fast follower/following/whisper counts by user ID (cheaper than full profile)
- **🎞️ User Videos** — paginated list of an UP主's complete video catalog
- **💬 Video Comments** — paginated comments on a single video, with reply samples
- **🎯 Video Danmaku** — bullet chat (弹幕) overlay text + timestamps for a single video (requires AID + CID)
- **🌐 Video Caption Metadata** — language list + signed subtitle URLs for a video (requires AID + BV + CID; URL points to a JSON subtitle file you fetch yourself)
- **🔍 Search Videos** — keyword search across Bilibili videos, paginated (~20 results/page)

💡 **TIP:** Run `Video Detail` first to get the `aid` and `cid` of any BV-ID video, then feed them into Comments / Danmaku / Caption operations.

## `bvid` (type: `string`):

📺 **Required for `Video Detail` and `Video Caption Metadata` operations.**

The Bilibili BV ID (always starts with `BV`, e.g. `BV1rpWjevEip`). You can find it:

- In any Bilibili video URL: `https://www.bilibili.com/video/{BV_ID}` → the trailing segment
- In the `bvid` field of any search or user-videos result row

💡 **TIP:** Use the `Search Videos` operation to discover BV IDs in any niche, then drill into individual videos with `Video Detail`.

⚠️ **Ignored** for User Profile, Comments (uses `aid`), Danmaku (uses `aid`+`cid`), and Search operations.

## `aid` (type: `string`):

🆔 **Required for `Video Comments`, `Video Danmaku`, and `Video Caption Metadata` operations.**

The numeric Bilibili video ID (also called `aid` or `av number`). You can find it:

- In the `aid` field of any `Video Detail` or `Search Videos` result row
- In legacy URLs: `https://www.bilibili.com/video/av{AID}`

💡 **TIP:** Always run `Video Detail` first to fetch the `aid` (and `cid`) for any BV-ID video, then use them for Comments / Danmaku / Caption.

⚠️ **Ignored** for User and Search operations.

## `cid` (type: `string`):

🧩 **Required for `Video Danmaku` and `Video Caption Metadata` operations.**

The Bilibili chapter ID (`cid`). Multi-part videos have one `cid` per part; single-part videos have one. You can find it:

- In the `cid` field of any `Video Detail` result row
- In `videoPages[].cid` for multi-part videos

💡 **TIP:** For multi-part videos, run Danmaku / Caption per `cid` to fetch each part separately.

⚠️ **Ignored** for non-danmaku / caption operations.

## `userId` (type: `string`):

👤 **Required for `User Profile`, `User Relation Stat`, and `User Videos` operations.**

The numeric Bilibili user ID (also called `mid`). You can find it:

- In a creator's space URL: `https://space.bilibili.com/{USER_ID}`
- In the `userId` / `mid` field of any video, search, or comment result row

💡 **TIP:** Use `Search Videos` to discover trending UP主, then use their `userId` to pull full profile or complete video catalogs.

⚠️ **Ignored** for video-specific and search operations.

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

🔍 **Required for `Search Videos` operation.**

Any Bilibili search query. Supports Chinese, English, and mixed queries:

- `python`
- `游戏` (games)
- `美食` (food)
- `anime review`

💡 **TIP:** Specific niches return higher-relevance results. Chinese-language queries surface more native UP主; English / mixed queries surface global content.

## `maxPages` (type: `integer`):

📄 **Applies to paginated operations** (User Videos, Video Comments, Search Videos). Ignored for single-record operations (Video Detail, User Profile, Relation Stat, Danmaku, Caption).

- **User Videos:** ~30 videos per page
- **Video Comments:** ~20 comments per page (with sub-comment samples)
- **Search Videos:** ~20 results per page (max 50 pages = 1,000 videos)

💡 **TIP:** Start small (1–3 pages) to preview results before scaling up.

⚠️ Hard cap: 50 pages to prevent runaway runs.

## Actor input object example

```json
{
  "operation": "searchVideo",
  "bvid": "BV1rpWjevEip",
  "aid": "113006243481679",
  "cid": "36010133667",
  "userId": "3546597933714079",
  "keyword": "python",
  "maxPages": 5
}
```

# Actor output Schema

## `output` (type: `string`):

Videos, profiles, comments, danmaku, captions, or search results — one flat row per upstream item with curated camelCase aliases (bvid, aid, cid, userId, viewCount, likeCount, coinCount, favoriteCount, videoTitle, videoPageUrl, userPageUrl, …) plus raw upstream fields spread alongside.

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

HTML report with run status, success/error row counts, success rate, pages fetched, duration, and the inputs used — written even on fatal crash.

# 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 = {
    "bvid": "BV1rpWjevEip",
    "aid": "113006243481679",
    "cid": "36010133667",
    "userId": "3546597933714079",
    "keyword": "python"
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/bilibili-video-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 = {
    "bvid": "BV1rpWjevEip",
    "aid": "113006243481679",
    "cid": "36010133667",
    "userId": "3546597933714079",
    "keyword": "python",
}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/bilibili-video-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "bvid": "BV1rpWjevEip",
  "aid": "113006243481679",
  "cid": "36010133667",
  "userId": "3546597933714079",
  "keyword": "python"
}' |
apify call sian.agency/bilibili-video-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=sian.agency/bilibili-video-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Bilibili Scraper — Video, UP主, Comments & Search",
        "description": "Bilibili scraper for video data, UP主 profiles, comments, danmaku (bullet chats), AI subtitle metadata & keyword search. KOL discovery, view/like/coin/favorite counts, creator analytics for China market research. Eight operations, one clean dataset per run. No API key.",
        "version": "1.1",
        "x-build-id": "NvDPoy7VbjKEVhkLx"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/sian.agency~bilibili-video-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-sian.agency-bilibili-video-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/sian.agency~bilibili-video-scraper/runs": {
            "post": {
                "operationId": "runs-sync-sian.agency-bilibili-video-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/sian.agency~bilibili-video-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-sian.agency-bilibili-video-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "operation"
                ],
                "properties": {
                    "operation": {
                        "title": "🎯 Operation — what do you want to scrape?",
                        "enum": [
                            "videoDetail",
                            "userDetail",
                            "userRelationStat",
                            "userVideos",
                            "videoComments",
                            "videoDanmu",
                            "videoCaption",
                            "searchVideo"
                        ],
                        "type": "string",
                        "description": "🎯 **PICK ONE OPERATION PER RUN.** Each run produces one clean dataset matching the chosen mode.\n\n- **📺 Video Detail** — deep scrape of a single Bilibili video by BV ID (title, description, view/like/coin/favorite/share/comment counts, cover, creator, video parts, tags)\n- **👤 User Profile** — full Bilibili UP主 profile by user ID (bio, level, verification, VIP status, live room, school, profession, join date)\n- **📈 User Relation Stat** — fast follower/following/whisper counts by user ID (cheaper than full profile)\n- **🎞️ User Videos** — paginated list of an UP主's complete video catalog\n- **💬 Video Comments** — paginated comments on a single video, with reply samples\n- **🎯 Video Danmaku** — bullet chat (弹幕) overlay text + timestamps for a single video (requires AID + CID)\n- **🌐 Video Caption Metadata** — language list + signed subtitle URLs for a video (requires AID + BV + CID; URL points to a JSON subtitle file you fetch yourself)\n- **🔍 Search Videos** — keyword search across Bilibili videos, paginated (~20 results/page)\n\n💡 **TIP:** Run `Video Detail` first to get the `aid` and `cid` of any BV-ID video, then feed them into Comments / Danmaku / Caption operations.",
                        "default": "searchVideo"
                    },
                    "bvid": {
                        "title": "📺 Video BV ID (for Video Detail / Video Caption)",
                        "type": "string",
                        "description": "📺 **Required for `Video Detail` and `Video Caption Metadata` operations.**\n\nThe Bilibili BV ID (always starts with `BV`, e.g. `BV1rpWjevEip`). You can find it:\n- In any Bilibili video URL: `https://www.bilibili.com/video/{BV_ID}` → the trailing segment\n- In the `bvid` field of any search or user-videos result row\n\n💡 **TIP:** Use the `Search Videos` operation to discover BV IDs in any niche, then drill into individual videos with `Video Detail`.\n\n⚠️ **Ignored** for User Profile, Comments (uses `aid`), Danmaku (uses `aid`+`cid`), and Search operations."
                    },
                    "aid": {
                        "title": "🆔 Video AID (for Video Comments / Danmaku / Caption)",
                        "type": "string",
                        "description": "🆔 **Required for `Video Comments`, `Video Danmaku`, and `Video Caption Metadata` operations.**\n\nThe numeric Bilibili video ID (also called `aid` or `av number`). You can find it:\n- In the `aid` field of any `Video Detail` or `Search Videos` result row\n- In legacy URLs: `https://www.bilibili.com/video/av{AID}`\n\n💡 **TIP:** Always run `Video Detail` first to fetch the `aid` (and `cid`) for any BV-ID video, then use them for Comments / Danmaku / Caption.\n\n⚠️ **Ignored** for User and Search operations."
                    },
                    "cid": {
                        "title": "🧩 Video CID (for Danmaku / Caption)",
                        "type": "string",
                        "description": "🧩 **Required for `Video Danmaku` and `Video Caption Metadata` operations.**\n\nThe Bilibili chapter ID (`cid`). Multi-part videos have one `cid` per part; single-part videos have one. You can find it:\n- In the `cid` field of any `Video Detail` result row\n- In `videoPages[].cid` for multi-part videos\n\n💡 **TIP:** For multi-part videos, run Danmaku / Caption per `cid` to fetch each part separately.\n\n⚠️ **Ignored** for non-danmaku / caption operations."
                    },
                    "userId": {
                        "title": "👤 User ID (for User Profile / User Videos / Relation Stat)",
                        "type": "string",
                        "description": "👤 **Required for `User Profile`, `User Relation Stat`, and `User Videos` operations.**\n\nThe numeric Bilibili user ID (also called `mid`). You can find it:\n- In a creator's space URL: `https://space.bilibili.com/{USER_ID}`\n- In the `userId` / `mid` field of any video, search, or comment result row\n\n💡 **TIP:** Use `Search Videos` to discover trending UP主, then use their `userId` to pull full profile or complete video catalogs.\n\n⚠️ **Ignored** for video-specific and search operations."
                    },
                    "keyword": {
                        "title": "🔍 Search Keyword (for Search Videos)",
                        "type": "string",
                        "description": "🔍 **Required for `Search Videos` operation.**\n\nAny Bilibili search query. Supports Chinese, English, and mixed queries:\n- `python`\n- `游戏` (games)\n- `美食` (food)\n- `anime review`\n\n💡 **TIP:** Specific niches return higher-relevance results. Chinese-language queries surface more native UP主; English / mixed queries surface global content."
                    },
                    "maxPages": {
                        "title": "📄 Max pages to fetch",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "📄 **Applies to paginated operations** (User Videos, Video Comments, Search Videos). Ignored for single-record operations (Video Detail, User Profile, Relation Stat, Danmaku, Caption).\n\n- **User Videos:** ~30 videos per page\n- **Video Comments:** ~20 comments per page (with sub-comment samples)\n- **Search Videos:** ~20 results per page (max 50 pages = 1,000 videos)\n\n💡 **TIP:** Start small (1–3 pages) to preview results before scaling up.\n\n⚠️ Hard cap: 50 pages to prevent runaway runs.",
                        "default": 5
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
