# Bilibili Scraper - Videos, Search, Popular & Uploader Stats (`rjmacarthy/bilibili-scraper`) Actor

Scrape public Bilibili (bilibili.com) data: popular feed, keyword search and video URLs with views, likes, coins, favorites and danmaku; uploader (UP主) follower stats; optional top comments. onlyNew mode for monitoring. No login, no browser.

- **URL**: https://apify.com/rjmacarthy/bilibili-scraper.md
- **Developed by:** [rj](https://apify.com/rjmacarthy) (community)
- **Categories:** Social media, Videos
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 video scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

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 - Videos, Search, Popular & Uploader Stats

**Bilibili Scraper** pulls public data from Bilibili (bilibili.com, B站), China's biggest video community. It reads the **popular (热门) feed**, runs **keyword searches** and looks up **specific videos**. Each video comes back with views, likes, coins, favorites, shares, danmaku and comment counts, plus its uploader. You can also get **uploader (UP主) follower stats** and, if you want them, each video's **top comments**, all from one Actor. It costs **$0.002 per video**, 10x less than the most-used Bilibili Actor ($0.02 per item). An **onlyNew** monitoring mode outputs (and charges) only videos you haven't seen before. If Bilibili holds a field back, the item says so in a status field instead of leaving it blank without explanation. No login, no cookies from an account, no browser.

### What data can you get?

| Videos (`type: "video"`) | Uploaders (`type: "uploader"`) | Comments (`type: "comment"`, optional) |
|---|---|---|
| BV id, AV id (aid), video URL | mid (user id), space URL | Comment id and link |
| Title, description, cover image | Name, bio (sign), avatar | Comment text |
| Duration (seconds), publish date (ISO) | Followers (fans), following | Likes, reply count |
| Category (zone / tname), tags (search) | Number of videos uploaded | Time (ISO) |
| Uploader mid, name and space URL | Total likes received | Commenter display name + mid (public handle) |
| Views, danmaku, likes, coins, favorites, shares, comments | Account level (0-6) | Video BV id and aid |
| Position in the popular feed / search results | Official verification title | |
| `detailsStatus` (`full` / `partial`), `commentsStatus` | | |

Only public creator and video data is collected. The Actor collects no e-mail addresses, phone numbers, gender, birthday or location.

### Use cases

- **Trend monitoring:** save the Bilibili popular (热门) feed every day and see which topics, games and creators are taking off in China.
- **Brand and product research:** search your brand, game or product (`原神`, `iPhone 17`, `Tesla`) and measure views, likes and coins on the videos about it.
- **Influencer (KOL) discovery and vetting:** compare UP主 follower counts, video counts, total likes and verification before a campaign.
- **Competitor tracking:** schedule a search sorted by newest with `onlyNew` to get only new videos about a keyword each day.
- **Content and sentiment research:** collect top comments for a quick read of the audience reaction.

### How to use it

1. Pick a **Mode**: `popular`, `search`, `videos` or `uploaders`.
2. Fill in the matching field: **Search keywords**, **Video URLs or BV ids**, or **Uploader mids or space URLs**.
3. Set **Max items** (default 50; 0 = no limit).
4. Optional: turn on **Include top comments**, or **Only new videos** for scheduled monitoring.
5. Click **Start**, then download JSON, CSV or Excel, or read the dataset through the API.

**Popular feed (the daily health-check input):**

```json
{ "mode": "popular", "maxItems": 10 }
```

**Search videos by keyword, newest first, only new ones on each scheduled run:**

```json
{ "mode": "search", "keywords": ["原神", "minecraft"], "searchOrder": "pubdate", "maxItems": 50, "onlyNew": true, "stateKey": "games-monitor" }
```

**Specific videos with their top comments:**

```json
{ "mode": "videos", "videoUrls": ["https://www.bilibili.com/video/BV1Ev4w63EW4/", "BV1zUx16tEKg"], "includeComments": true }
```

**Uploader (UP主) stats:**

```json
{ "mode": "uploaders", "uploaders": ["546195", "https://space.bilibili.com/927587", "517327498"] }
```

### Output example

Real items from a local run on 3 Nov 2026 (one video, one uploader and one comment; the commenter's name is replaced here):

```json
[
  {
    "type": "video",
    "id": "BV1zUx16tEKg",
    "aid": 117535236296957,
    "url": "https://www.bilibili.com/video/BV1zUx16tEKg/",
    "title": "180万一平米！假装要给男友买义乌1700万9平米的爆火房…他震惊了！",
    "description": "180万一平米！！！震惊了！！！",
    "coverUrl": "https://i1.hdslb.com/bfs/archive/c3938ea496ad80f58972e8e394fcf2e53ada39ce.jpg",
    "durationSec": 613,
    "publishedAt": "2026-11-01T03:00:00.000Z",
    "category": "日常",
    "uploaderMid": "2342793",
    "uploaderName": "是王小白呀",
    "uploaderUrl": "https://space.bilibili.com/2342793",
    "views": 555971,
    "danmaku": 1660,
    "likes": 14755,
    "coins": 2167,
    "favorites": 1993,
    "shares": 1207,
    "replies": 372,
    "tags": null,
    "source": "popular",
    "searchKeyword": null,
    "position": 1,
    "detailsStatus": "full",
    "commentsStatus": "ok",
    "scrapedAt": "2026-11-03T10:01:16.895Z"
  },
  {
    "type": "uploader",
    "id": "546195",
    "url": "https://space.bilibili.com/546195",
    "name": "老番茄",
    "sign": "新浪微博：_老番茄_",
    "fans": 20867223,
    "following": 7,
    "archiveCount": 683,
    "likes": 196657353,
    "level": 6,
    "officialVerify": "2025百大UP主、2025年度商业影响力奖UP主、2022年度联合创作奖UP主",
    "avatarUrl": "https://i0.hdslb.com/bfs/face/bc5ca101313d4db223c395d64779e76eb3482d60.jpg",
    "scrapedAt": "2026-11-03T10:01:20.699Z"
  },
  {
    "type": "comment",
    "id": "319067527793",
    "url": "https://www.bilibili.com/video/BV1zUx16tEKg/#reply319067527793",
    "videoId": "BV1zUx16tEKg",
    "aid": 117535236296957,
    "text": "500万涨到1700万，这是在洗钱还是在干什么见不得人的…",
    "likes": 35,
    "replyCount": 10,
    "publishedAt": "2026-11-03T08:06:21.000Z",
    "commenterName": "commenter1",
    "commenterMid": null,
    "scrapedAt": "2026-11-03T10:01:17.393Z"
  }
]
```

The dataset has three views: **Videos**, **Uploaders** and **Comments**. A `RUN_SUMMARY` record in the key-value store lists each input's status, the item counts, the request count and any warnings.

### Pricing

Pay per result. You pay only for items saved to the dataset:

| Event | Price |
|---|---|
| `video` - one video | **$0.002** |
| `uploader` - one uploader profile | **$0.002** |
| `comment` - one comment | **$0.0003** |

Worked examples: **1,000 videos ≈ $2.00**. 100 popular videos with their top 3 comments = 100 × $0.002 + 300 × $0.0003 = **$0.29**. 50 uploader profiles = **$0.10**. In `onlyNew` mode, videos you have already seen are skipped and not charged. The run stops cleanly when it reaches your **Maximum cost per run**.

### Monitoring new videos (onlyNew)

Turn on **Only new videos** in `popular` or `search` mode and schedule the Actor (daily, hourly). The first run outputs everything and remembers it. Later runs with the same **Monitor name (state key)** output only videos not seen before. For keyword monitoring, use `"searchOrder": "pubdate"` (newest first). Use a different state key for each independent monitor.

### Tips and limits

- **Comments: at most ~3 per video.** Bilibili shows visitors who are not logged in only the top ~3 hot comments per video, and this Actor never logs in. `maxCommentsPerVideo` is an upper limit. Videos where Bilibili returned fewer comments than you asked for get `commentsStatus: "limited"`. Each video with comments costs one extra request.
- **Search results have no coins or shares.** Bilibili's search API does not return them, so search items have `coins`/`shares` = null and `detailsStatus: "partial"`. Popular-feed and video-mode items have all stats (`"full"`).
- **Tags** are only filled for search results (the popular and video-detail endpoints don't include them); elsewhere `tags` is null.
- **Video mode on cloud IPs:** Bilibili's video-detail endpoint sometimes answers HTTP 412 (risk control) to datacenter IPs. The Actor then looks each video up through search instead: those items have `source: "search-fallback"` and `detailsStatus: "partial"`, and the run summary includes a warning. AV-only ids can't use the fallback, so pass BV ids.
- **Limits:** the popular feed has a few hundred videos. Search returns up to 50 pages (about 1,000 videos) per keyword. `maxItems` applies per keyword in search mode.
- **Speed and politeness:** at most 2 requests per second. About 20 videos per request in popular and search mode.
- Deleted, private or region-locked videos are reported as failed inputs. The rest of the run carries on.

### FAQ

**Is it legal to scrape Bilibili?**
This Actor reads only public data that anyone can see without logging in: video stats, public creator profiles, and the top comments with their public display names. It does not log in, solve captchas or bypass access controls, and it collects no contact details. Bilibili's API robots.txt disallows crawling, so keep volumes moderate and use the data responsibly. You are responsible for complying with Bilibili's terms, copyright and data-protection law (such as GDPR or China's PIPL) in your use case. If in doubt, ask a lawyer.

**Do I need a Bilibili account or cookies?**
No. The Actor opens the Bilibili homepage once to get the anonymous visitor cookie (`buvid3`) that every first-time visitor receives, then calls the public JSON APIs.

**Do I need a proxy?**
Usually not: the popular feed and uploader cards work from Apify's datacenter IPs. If a run reports "Bilibili risk control refused the request (HTTP 412)", enable **Apify Proxy** (datacenter). **Residential proxies are not supported**: if you select them, the Actor falls back to Apify datacenter proxy and logs a warning.

**Why are some fields null?**
Bilibili doesn't return them on that endpoint (see Tips). `detailsStatus` and `commentsStatus` tell you which case you're in, so a missing value is never silent.

**Can I get danmaku (bullet comments) text, subtitles or the video file?**
No. The Actor reports the danmaku *count* and video metadata, not video files or danmaku text.

### Integrations

- **API:** start runs and read datasets with the Apify API or the JavaScript/Python clients.
- **Make, Zapier, n8n:** use the Apify modules to start the Actor on a schedule and send new videos to Google Sheets, Slack or a database.
- **MCP / AI agents:** call the Actor from Claude, ChatGPT or any MCP client through Apify's MCP server.
- **Webhooks:** get notified when a run finishes.

### Changelog

- **0.1** (Nov 2026): first release with popular, search, videos and uploaders modes, optional top comments, onlyNew monitoring and per-event pricing.

### More scrapers by the same developer

- [AI Visibility Tracker: ChatGPT, Perplexity, Gemini, Claude](https://apify.com/rjmacarthy/ai-search-visibility-tracker)
- [Google Ads Transparency Scraper](https://apify.com/rjmacarthy/google-ads-transparency-scraper)
- [Substack Scraper](https://apify.com/rjmacarthy/substack-scraper)
- [Telegram Channel Scraper](https://apify.com/rjmacarthy/telegram-channel-scraper)
- [ATS Jobs Scraper: Greenhouse, Lever, Ashby & Workday](https://apify.com/rjmacarthy/ats-jobs-scraper)
- [Dice Jobs Scraper](https://apify.com/rjmacarthy/dice-jobs-scraper)

Browse all my Actors on [my Apify Store profile](https://apify.com/rjmacarthy).

### Support

Found a bug or need a field? Open an issue on the Actor's **Issues** tab. Include the run ID and your input.

# Actor input Schema

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

What to scrape: the popular (热门) feed, keyword search, specific videos, or uploader (UP主) profiles.

## `keywords` (type: `array`):

Search mode: one or more keywords (Chinese or English). Each keyword is searched separately; max items applies per keyword.

## `searchOrder` (type: `string`):

Search mode: sort by relevance, most played, newest, most danmaku or most favorited. Use "newest" with onlyNew to monitor a keyword.

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

Videos mode: bilibili.com/video/... URLs, b23.tv/BV... links or bare BV ids (e.g. BV1GJ411x7h7).

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

Uploaders mode: numeric user ids (mid) or space.bilibili.com/<mid> URLs. Outputs public creator stats only.

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

Maximum videos (popular, videos), videos per keyword (search) or uploaders (uploaders mode). 0 = no limit (the popular feed has a few hundred videos; search up to ~1,000 per keyword).

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

Also output the top public comments of every video (one extra request per video, charged per comment). Bilibili shows only the top ~3 hot comments to visitors who are not logged in.

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

Upper limit of comments per video when "Include top comments" is on.

## `onlyNew` (type: `boolean`):

Popular and search modes: skip videos already output by earlier runs with the same state key, so a scheduled run returns (and charges) only new videos.

## `stateKey` (type: `string`):

Name of the onlyNew memory. Use a different name for each independent monitor.

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

Optional. Use Apify Proxy (datacenter) if Bilibili refuses requests from the run's IP (HTTP 412). Residential proxies are not supported: if selected, the Actor falls back to Apify datacenter proxy.

## Actor input object example

```json
{
  "mode": "popular",
  "keywords": [
    "minecraft",
    "原神"
  ],
  "searchOrder": "totalrank",
  "videoUrls": [
    "https://www.bilibili.com/video/BV1GJ411x7h7/"
  ],
  "uploaders": [
    "546195",
    "https://space.bilibili.com/927587"
  ],
  "maxItems": 10,
  "includeComments": false,
  "maxCommentsPerVideo": 20,
  "onlyNew": false,
  "stateKey": "default",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `videos` (type: `string`):

One row per video: title, uploader, views, likes, coins, favorites, danmaku, comments, duration and publish date.

## `uploaders` (type: `string`):

One row per uploader: followers, videos, total likes, level and verification.

## `comments` (type: `string`):

One row per comment: text, likes, replies, time and commenter handle.

## `all` (type: `string`):

Every field of every item.

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

Per-input status, counts, request statistics and warnings.

# 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 = {
    "mode": "popular",
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("rjmacarthy/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 = {
    "mode": "popular",
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("rjmacarthy/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 '{
  "mode": "popular",
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call rjmacarthy/bilibili-scraper --silent --output-dataset

```

## MCP server setup

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