# Bilibili Video Scraper (`axiomworks/bilibili-scraper`) Actor

Scrape Bilibili videos by keyword, video URL, creator, or popular list and collect titles, descriptions, creator IDs, publish dates, durations, views, likes, and cover URLs. Optionally include top comments and time-synced danmaku; no account is required.

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

## Pricing

from $7.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

**Returns:** one row per Bilibili video with bvid, title, authorName, publishedAt, views, likes and sourceUrl.
**Input:** `{"mode":"search","searchTerms":["python tutorial"],"maxItems":10,"includeComments":false,"includeDanmaku":false}`
**Best for:** Bilibili creator discovery, video engagement research and search trend monitoring.

```json
{
  "bvid": "BV1rpWjevEip",
  "title": "【全748集】目前B站最全最细的Python零基础全套教程，2026最新版，包含所有干货！七天就能从小白到大神！少走99%的弯路！存下吧！很难找全的！",
  "authorName": "Python官方课程",
  "publishedAt": "2024-08-22T14:59:18.000Z",
  "views": 20754385,
  "likes": 571611,
  "sourceUrl": "https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=python%20tutorial&page=1&page_size=50"
}
```

### What does Bilibili Scraper do?

This Bilibili scraper collects public video data through the public Bilibili API from Bilibili (bilibili.com), the large Chinese video platform. You can search videos by keyword, fetch specific videos by URL or BV id, list every upload of a creator, or read Bilibili's popular (trending) list. For each video you get the title, description, creator name and id, publish date, duration, view count, like count, danmaku count, comment count and cover image URL.

Two optional extras go deeper. Turn on comments to attach the top comments of each video, and turn on danmaku to attach the time-synced bullet comments that scroll over the video. Two more optional switches add engagement details (favorites, coins, shares, part count) and the uploader's profile (followers, following, level, bio, video count, total likes). A further optional step uses a third-party AI processor to label each video with a content category.

No login or account is needed. The Actor reads the same public endpoints the Bilibili website uses, with polite request pacing and automatic retries on a fresh proxy session when Bilibili answers with its risk-control responses. This Actor is not affiliated with or endorsed by Bilibili.

Typical uses:

- Track what Chinese creators publish on a topic and how many views each video gets.
- Build a dataset of video titles and descriptions for language or market research.
- Monitor a creator's uploads over time.
- Collect audience reactions from comments and danmaku for sentiment analysis.
  Tip: Watch the popular list for emerging trends.

### What data can you get?

Every record is one video. Fields that a given mode cannot provide are returned as null.

| Field | Type | Description |
|---|---|---|
| `id` | string | Stable id, equal to the BV id |
| `bvid` | string | Bilibili BV video id |
| `aid` | number | Legacy numeric video id |
| `title` | string | Video title (search highlight tags removed) |
| `description` | string | Description written by the uploader |
| `authorName` | string | Creator display name |
| `authorMid` | number | Creator numeric id |
| `publishedAt` | string | Publish time, ISO 8601 UTC |
| `durationSeconds` | number | Video length in seconds |
| `views` | number | Play count |
| `likes` | number | Like count (in creatorUploads mode it is read from the video detail endpoint) |
| `danmakuCount` | number | Number of danmaku on the video |
| `commentCount` | number | Number of comments |
| `coverUrl` | string | Cover image URL |
| `tags` | array | Video tags (from search results, or the tag endpoint in other modes) |
| `url` | string | Public video URL |
| `sourceUrl` | string | Endpoint the record came from |
| `comments` | array | Top comments, only with includeComments |
| `favorites` | number | Favorite count, only with includeDetails |
| `coins` | number | Coins thrown at the video, only with includeDetails |
| `shares` | number | Share count, only with includeDetails |
| `pageCount` | number | Number of parts in the video, only with includeDetails |
| `authorFollowers` | number | Creator follower count, only with includeCreatorProfile |
| `authorFollowing` | number | Accounts the creator follows, only with includeCreatorProfile |
| `authorLevel` | number | Creator account level, only with includeCreatorProfile |
| `authorVerifiedTitle` | string | Creator verification title if any, only with includeCreatorProfile |
| `authorBio` | string | Creator signature text, only with includeCreatorProfile |
| `authorVideoCount` | number | Creator upload count, only with includeCreatorProfile |
| `authorTotalLikes` | number | Creator total likes, only with includeCreatorProfile |
| `danmaku` | array | Danmaku texts with video time, only with includeDanmaku |
| `contentCategory` | string | AI label, only with enrichWithAI |

Each comment holds `rpid`, `authorName`, `authorMid`, `message`, `likes`, `replyCount` and `publishedAt`. Each danmaku holds `text`, `timeSeconds` and `sentAt`.

### How to use Bilibili Scraper

1. Open the Actor and pick a **mode**.
2. For `search`, enter one or more keywords. For `video`, paste video URLs or BV ids. For `creatorUploads`, paste creator page URLs such as `https://space.bilibili.com/1458132`. For `popular`, no target is needed.
3. Set **Max videos** to the number of results you want.
4. Optionally enable comments, danmaku or AI category.
5. Keep the proxy on residential. Bilibili blocks datacenter addresses after only a few requests.
6. Click Start and download the dataset as JSON, CSV, Excel or HTML, or read it through the API.

Search returns up to about 1000 results per keyword, which is a limit of Bilibili's own search. Results are de-duplicated by BV id within a run, and the Actor never returns more than Max videos.

#### Choosing a mode

**Search** is the best starting point when you know a topic but not the creators. Each keyword is paged until Max videos is reached or Bilibili runs out of results. With several keywords, they are processed in order and a video that matches more than one keyword is returned once.

**Video** is for a known list of videos. It returns the most accurate counters because it reads the video detail endpoint. Full www.bilibili.com and m.bilibili.com video URLs, bare BV IDs and legacy av IDs are accepted. For example, use \["BV1rpWjevEip"] or \["av113006243481679"] in startUrls with mode="video". Query strings and video part parameters on full URLs are accepted; the output remains one row for the video.

**Creator uploads** walks the upload list of each creator newest first, thirty videos per page. The list gives views, comment count and danmaku count; the Actor reads likes from the video detail endpoint. Supply a creator page URL or numeric creator ID in startUrls, for example \["1458132"].

**Popular** returns the current trending list in ranked order. It needs no input other than Max videos.

#### Tips for reliable runs

Tip: Keep Max videos modest while testing, then raise it. Requests are spaced by one to two seconds on purpose, so large runs take time.

- Comments and danmaku each add requests per video. For a quick list of videos, leave them off.
  Tip: If a run reports that requests failed, check that the proxy setting still uses a residential group and run again.

### Input

| Field | Type | Description |
|---|---|---|
| `mode` | string | `search`, `video`, `creatorUploads` or `popular`. Default `search` |
| `searchTerms` | array | Keywords for search mode |
| `startUrls` | array | Video URLs or BV ids (video mode), creator URLs or ids (creatorUploads mode) |
| `maxItems` | integer | Maximum videos returned, 1 to 10000, default 50 |
| `includeComments` | boolean | Attach top comments, default false |
| `commentsPerVideo` | integer | Comments per video, default 20 |
| `includeDanmaku` | boolean | Attach danmaku, default false |
| `includeDetails` | boolean | Add favorites, coins, shares and part count, default false |
| `includeCreatorProfile` | boolean | Add creator followers, level, bio and totals, default false |
| `danmakuPerVideo` | integer | Danmaku per video, default 100 |
| `enrichWithAI` | boolean | Add an AI content category, default false |
| `proxyConfiguration` | object | Apify Proxy settings, residential by default |

Example input:

```json
{
  "mode": "search",
  "searchTerms": ["python tutorial"],
  "maxItems": 10,
  "includeComments": false,
  "includeDanmaku": false,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

Example for a single video with comments and danmaku:

```json
{
  "mode": "video",
  "startUrls": ["https://www.bilibili.com/video/BV1rpWjevEip/"],
  "includeComments": true,
  "commentsPerVideo": 20,
  "includeDanmaku": true,
  "danmakuPerVideo": 50
}
```

If an input is invalid, for example a URL that is not a Bilibili video, the run fails right away with a message that says what to fix. A valid target that has no videos or remains blocked ends successfully with zero items. The final status names the relevant input to change: broaden searchTerms, check video or creator IDs in startUrls, or retry the popular list later. Check residential proxy availability if requests are blocked. Each target is handled separately, so a failed target does not prevent trying the next one. Targets that have not produced a result have a 70-second request budget before the Actor moves on.

### Output

A shortened real record from a local search run on October 11, 2026 (see the dataset for complete data). Counters and titles can change:

```json
{
  "id": "BV1rpWjevEip",
  "bvid": "BV1rpWjevEip",
  "aid": 113006243481679,
  "title": "【全748集】目前B站最全最细的Python零基础全套教程，2026最新版，包含所有干货！七天就能从小白到大神！少走99%的弯路！存下吧！很难找全的！",
  "authorName": "Python官方课程",
  "authorMid": 3546597933714079,
  "publishedAt": "2024-08-22T14:59:18.000Z",
  "durationSeconds": 143894,
  "views": 20664837,
  "likes": 568771,
  "danmakuCount": 132638,
  "commentCount": 359083,
  "coverUrl": "https://i2.hdslb.com/bfs/archive/a979056b1a32012cdd00d48fbc3732d253e30620.jpg",
  "url": "https://www.bilibili.com/video/BV1rpWjevEip/",
  "sourceUrl": "https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=python%20tutorial&page=1&page_size=50"
}
```

Titles, descriptions, comments and danmaku are returned in the original language, mostly Chinese. Nothing is translated.

### How much does it cost?

The Actor is charged per result, meaning per video returned. An extra event applies only to videos that were successfully labelled when AI category is on. Open the Pricing tab of the Actor for the current rates. Comments and danmaku do not add separate charges, but they add requests and therefore run time.

### Use with AI agents (MCP)

Connect an MCP client to the Apify MCP server and expose this Actor as a tool:

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

Example prompts:

- "Find the 20 most viewed Bilibili videos about machine learning and list title, creator and views."
- "Get the latest 30 uploads of https://space.bilibili.com/1458132."
- "Fetch the top 20 comments and 50 danmaku for this Bilibili video."

### Integrations and API

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("axiomworks/bilibili-scraper").call(run_input={
    "mode": "search", "searchTerms": ["python tutorial"], "maxItems": 10,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["views"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<APIFY_TOKEN>' });
const run = await client.actor('axiomworks/bilibili-scraper').call({
    mode: 'search', searchTerms: ['python tutorial'], maxItems: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.dir(items);
```

cURL:

```bash
curl -X POST "https://api.apify.com/v2/acts/axiomworks~bilibili-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"search","searchTerms":["python tutorial"],"maxItems":10}'
```

You can also connect the dataset to Make, Zapier, Google Sheets or webhooks through Apify integrations.

### FAQ

**Do I need a Bilibili account?** No. Only public data that loads without logging in is collected.

**Why is a residential proxy the default?** Bilibili answers datacenter addresses with risk-control errors after a few requests. Residential traffic is far more reliable, and the Actor retries on a fresh session when it is blocked.

**Why does a search return fewer videos than I asked for?** Bilibili search exposes at most about 1000 results per keyword, and a creator or keyword may simply have fewer videos.

**How does creatorUploads mode get `likes`?** The upload list has no like counts, so the Actor makes one extra detail request per video to read them; runs in this mode are somewhat slower.

**Why are comments fewer than the comment count?** Only the top comments are collected, up to commentsPerVideo, and Bilibili limits how deep anonymous paging goes.

**What is danmaku?** Short comments tied to a moment in the video that scroll across the screen. Each one has its text and the video time in seconds.

**How does the AI category work?** When enabled, the title and description are sent to a third-party AI processor that picks one of tutorial, entertainment, news, gaming, music or other. If the processor is unavailable the video is still returned without a category and no enrichment charge is made.

**Can I run it on a schedule?** Yes, use Apify schedules to monitor a creator or keyword regularly.

### Is it legal to scrape Bilibili?

The Actor collects only information that is publicly visible without logging in, and it does not bypass logins or CAPTCHAs. Whether your use of the data is lawful depends on your jurisdiction, the purpose and how you handle personal data such as creator names and comments. Bilibili's terms of service may restrict automated access, and you are responsible for complying with them and with data protection law such as GDPR. Collect only what you need, do not republish copyrighted content, and seek legal advice for commercial use.

### Feedback

If a field is missing, a mode misbehaves or you need another data point, open an issue from the Actor page on Apify. Include the input you used and the run link so the problem can be reproduced quickly.

# Actor input Schema

## `searchTerms` (type: `array`):

Keywords to search in mode="search", e.g. \["python tutorial"] or \["机器学习"]. Supply at least one non-empty string. Results stay in their original language; up to about 1000 matching videos per keyword. Ignored in other modes.

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

Choose "search" for searchTerms, "video" for video URLs or IDs in startUrls, "creatorUploads" for creator URLs or numeric IDs in startUrls, or "popular" with no target. Example: "search". Default "search".

## `startUrls` (type: `array`):

Targets for mode="video": full www.bilibili.com or m.bilibili.com video URLs, BV IDs such as "BV1rpWjevEip", or AV IDs such as "av113006243481679". For mode="creatorUploads": "https://space.bilibili.com/1458132" or "1458132". Supply an array of strings. Ignored in search/popular modes. Default \[].

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

Limit the total videos returned across all keywords or targets, e.g. 10. Integer 1-10000, default 50. Stops at this limit when enough videos exist; fewer are returned when targets have fewer matches.

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

Set true to attach top comments in each video's comments array, e.g. true. Default false. Adds paginated requests; commentsPerVideo controls the limit. Leave false for faster video discovery.

## `commentsPerVideo` (type: `integer`):

Limit comments per video when includeComments=true, e.g. 20. Integer 1-1000, default 20. Fewer may be available. Ignored when includeComments=false.

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

Set true to attach time-synced bullet comments in each video's danmaku array, e.g. true. Default false. Adds requests; danmakuPerVideo controls the limit. Leave false for faster video discovery.

## `danmakuPerVideo` (type: `integer`):

Limit timed danmaku entries per video when includeDanmaku=true, e.g. 100. Integer 1-5000, default 100. Fewer may be available. Ignored when includeDanmaku=false.

## `includeDetails` (type: `boolean`):

Set true to add favorites, coins, shares and pageCount, e.g. true. Default false. May add a video detail request in search or creatorUploads mode. Leave false for a smaller result record.

## `includeCreatorProfile` (type: `boolean`):

Set true to add authorFollowers, authorFollowing, authorLevel, authorVerifiedTitle, authorBio, authorVideoCount and authorTotalLikes, e.g. true. Default false. Adds one request per distinct creator; unavailable profile values are null.

## `enrichWithAI` (type: `boolean`):

Set true to classify title and description as tutorial, entertainment, news, gaming, music or other in contentCategory, e.g. true. Default false. Uses a third-party AI processor; an enriched-result event applies only when classification succeeds. Limit 500 AI calls per run.

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

Provide Apify Proxy settings, e.g. {"useApifyProxy":true,"apifyProxyGroups":\["RESIDENTIAL"]}, or custom proxyUrls. Default uses residential Apify Proxy. If requests stay blocked, check proxy availability and retry later.

## Actor input object example

```json
{
  "searchTerms": [
    "python tutorial"
  ],
  "mode": "search",
  "startUrls": [],
  "maxItems": 10,
  "includeComments": false,
  "commentsPerVideo": 20,
  "includeDanmaku": false,
  "danmakuPerVideo": 100,
  "includeDetails": false,
  "includeCreatorProfile": false,
  "enrichWithAI": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "searchTerms": [
        "python tutorial"
    ],
    "mode": "search",
    "maxItems": 10,
    "includeComments": false,
    "includeDanmaku": false,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/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 = {
    "searchTerms": ["python tutorial"],
    "mode": "search",
    "maxItems": 10,
    "includeComments": False,
    "includeDanmaku": False,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/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 '{
  "searchTerms": [
    "python tutorial"
  ],
  "mode": "search",
  "maxItems": 10,
  "includeComments": false,
  "includeDanmaku": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call axiomworks/bilibili-scraper --silent --output-dataset

```

## MCP server setup

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