# Bilibili Scraper | Videos, Comments & Creators (`peerless_columbine/bilibili-all-in-one-scraper-api`) Actor

Extract Bilibili video details, search results, comments, creator profiles, danmaku and live-room data. Use familiar input formats, incremental collection and explicit coverage warnings. Full subtitles are not guaranteed.

- **URL**: https://apify.com/peerless\_columbine/bilibili-all-in-one-scraper-api.md
- **Developed by:** [tingyou333 zhuang](https://apify.com/peerless_columbine) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 video discovery results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Bilibili Scraper | Videos, Comments & Creators

Collect Bilibili video, comment, creator, danmaku and live-room data for Chinese video research. Choose a collection mode and export structured rows with explicit source-coverage information.

[Quick start](#quick-start) · [Workflows](#common-workflows) · [Pricing](#pricing) · [Input reference](#input-reference) · [Output reference](#output-reference) · [API and automation](#api-and-automation) · [FAQ](#faq) · [Technical reference](#technical-reference)

### What you can do

- **Multiple public-data modes** — Search, popular/ranking, video details, comments, creator profiles/catalogs, relations, danmaku and live rooms.
- **Thread and reaction context** — Request comment replies and optional per-video danmaku reaction profiles.
- **Migration and monitoring** — Accept mode or operation aliases and use persisted delta state for recurring collection.
- **Visible completeness** — Warnings, missing fields and source requirements distinguish partial retrieval from complete output.

#### Who uses it

- Creator and agency research: examine public creator profiles, catalogs and engagement.
- Brand and content teams: monitor topic searches, popular videos and public comments.
- Analysts: study timed danmaku reactions and export data for external analysis.

### Quick start

1. Open **Input**, enter your target and a small result limit.
2. Click **Start** and inspect the dataset and run log.
3. Export JSON/CSV, or save the input as a Task for recurring runs.

```json
{
  "mode": "popular",
  "maxResults": 5
}
```

Form prefills, schema defaults and empty API input can differ. Use explicit targets and limits; see the technical reference for source and default behavior.

<details>
<summary>Default input behavior and source options</summary>

Empty input selects `popular` with up to 100 primary videos. Mode-specific targets are required for search, video, creator and live requests.

</details>

#### Import an existing configuration

Use `zhorexInput` or `sianInput` to paste the corresponding competitor's complete input JSON. Put additional options inside the selected object. Native form defaults do not override it. For SIAN operations, omitted result budgets are derived from `maxPages`; explicit native caps still take precedence.

```json
{"sianInput": {"operation": "searchVideo", "keyword": "人工智能", "maxPages": 1, "maxResults": 10}}
```

The import fields preserve documented input names, types and defaults. Output metadata and source availability can differ. Full subtitle text is not provided; available caption metadata is a separate source-dependent result.

### Common workflows

#### Search recent videos

```json
{
  "mode": "search",
  "searchQuery": "人工智能教程",
  "sortOrder": "pubdate",
  "maxResults": 10
}
```

#### Collect comments and replies

```json
{
  "mode": "video_comments",
  "videoUrls": [
    "BV1rpWjevEip"
  ],
  "maxComments": 20,
  "includeReplies": true
}
```

#### Inspect one video

```json
{
  "mode": "video_detail",
  "videoUrls": [
    "BV1rpWjevEip"
  ],
  "maxResults": 1
}
```

### Output at a glance

Illustrative field subset below; these are example values, not a captured customer review or a claim about source coverage. Native and compatibility output profiles can differ.

```json
{
  "type": "video",
  "bvid": "BV1rpWjevEip",
  "title": "Illustrative video title",
  "url": "https://www.bilibili.com/video/BV1rpWjevEip",
  "coverage": "partial",
  "warnings": [
    "Illustrative warning: one optional source field was unavailable."
  ]
}
```

Full subtitle retrieval is not guaranteed and is outside the current parity target. Source access and mode availability vary; a successful run is not proof that every requested field was retrieved. Optional enrichment can add output rows and costs.

### Pricing

Pay per delivered event, with automatic discounts based on **your Apify subscription plan**. These are result fees in USD, not separate subscriptions sold by this Actor. All tiers have the same Actor features. **Apify compute, storage, transfers and any proxy usage are charged additionally.**

| Billable event (1,000 events) | Free | Starter | Scale | Business |
|---|---:|---:|---:|---:|
| Video Discovery Result | $3 | $2.5 | $2 | $1.5 |
| Video Detail Result | $5 | $4 | $3 | $2.5 |
| Danmaku Profile | $10 | $8 | $6 | $5 |
| Profile Result | $5 | $4 | $3 | $2.5 |
| Relation Result | $5 | $4 | $3 | $2.5 |
| Live Result | $5 | $4 | $3 | $2.5 |

Platinum and Diamond currently use the Business rate. The **Pricing** tab is the source of truth for the active schedule and your applicable plan.

- **Video Discovery Result**: Charged for each delivered video discovery result. Failed result rows carry no custom event fee. Platform usage is additional.
- **Video Detail Result**: Charged for each delivered video detail result. Failed result rows carry no custom event fee. Platform usage is additional.
- **Danmaku Profile**: Charged for each delivered danmaku profile. Failed result rows carry no custom event fee. Platform usage is additional.
- **Profile Result**: Charged for each delivered profile result. Failed result rows carry no custom event fee. Platform usage is additional.
- **Relation Result**: Charged for each delivered relation result. Failed result rows carry no custom event fee. Platform usage is additional.
- **Live Result**: Charged for each delivered live result. Failed result rows carry no custom event fee. Platform usage is additional.

Example on the Free plan: 10 / 1,000 / 10,000 **Video Discovery Result** events cost $0.03 / $3 / $30 in result fees, plus platform usage. Mixed Bilibili event types are summed separately.

There is no additional developer setup or monthly rental fee. A run with no billable results can still consume platform resources. Start small, cap results and review run costs before scheduling a larger workload. Requested counts are ceilings, not guaranteed deliveries.

### Input reference

Fields below are grouped like the Input form. Optional fields need not be supplied. Compatibility input envelopes and transformations are explained in the technical reference.

#### Targets and collection

| Field | Type | Default | Meaning |
|---|---|---|---|
| `mode` | string | Not set | Canonical mode. Leave empty when using the SIAN-compatible operation field. |
| `operation` | string | Not set | Optional compatibility alias: searchVideo, videoDetail, videoComments, userDetail, userRelationStat, userVideos, videoDanmu, videoCaption. |
| `searchQuery` | string | Not set | Keyword used in search mode. |
| `keyword` | string | Not set | SIAN-compatible alias for searchQuery. |
| `autoLocalize` | boolean | true | Also search a small set of common Chinese brand-name aliases when available. |
| `searchAliases` | array | \[] | Extra terms to search and merge with the primary keyword. |
| `pubtimeBegin` | string | Not set | YYYY-MM-DD |
| `pubtimeEnd` | string | Not set | YYYY-MM-DD |
| `videoUrls` | array | \[] | One or more Bilibili video URLs, BVIDs, or numeric AIDs. |
| `bvid` | string | Not set | Single BVID compatibility alias for video modes. |
| `aid` | string | Not set | Single numeric AID compatibility alias. Caption/transcript can also use aid together with cid. |
| `cid` | string | Not set | Single video CID, used directly by danmaku/caption/transcript modes when applicable. |
| `userIds` | array | \[] | One or more Bilibili creator MIDs. |
| `userId` | string | Not set | Single creator MID compatibility alias. |
| `liveRoomIds` | array | \[] | One or more Bilibili live room IDs or live-room URLs. |
| `roomId` | string | Not set | Single live room ID compatibility alias. |
| `category` | string | "all" | Category filter for popular and ranking modes. |
| `includeComments` | boolean | false | For discovery modes, append public comment rows for discovered videos while respecting the global maxResults row cap. The Actor reserves enrichment capacity before discovery so this flag is not a silent no-op when discovery could otherwise fill the cap. |
| `includeReplies` | boolean | false | When scraping comments, expand available child reply chains. |
| `includeDanmaku` | boolean | false | For discovery modes, append one aggregate danmaku profile per discovered video. |
| `danmakuSampleSize` | integer | 25 | Maximum number of representative danmaku texts kept in a danmaku profile. |
| `includeCreator` | boolean | false | For discovery modes, append public creator profile rows for creators in the video results. |
| `includeTranscript` | boolean | false | For discovery modes, append native transcript rows when Bilibili exposes public subtitle tracks. |
| `enrichDetails` | boolean | false | More complete engagement fields at the cost of additional requests. |
| `requestDelayMillis` | integer | 120 | Minimum spacing in milliseconds between HTTP request starts across the client. |
| `sentimentAnalysis` | boolean | false | Local SnowNLP polarity and -1 to +1 score for comments and video titles/descriptions. Use at least 512 MB memory. No external API fee. This heuristic is not a validated accuracy guarantee; non-Chinese text is tagged no\_chinese\_text. |

#### Filters and ordering

| Field | Type | Default | Meaning |
|---|---|---|---|
| `sortOrder` | string | "totalrank" | Sort video search results by relevance, views, publish time, danmaku, favorites, or score. |
| `durationFilter` | string | "any" | Limit search results by Bilibili duration bucket. |
| `sortComments` | string | "hot" | Preferred public comment ordering. |

#### Result limits and cost

| Field | Type | Default | Meaning |
|---|---|---|---|
| `maxResults` | integer | 100 | Primary result limit. In discovery modes, optional enrichment adds rows without reducing requested videos. maxOutputRows and the Apify charge budget remain hard caps. Set maxResultsScope=global for legacy total-row semantics. |
| `maxPages` | integer | Not set | SIAN-compatible page cap. maxResults remains the hard row cap. |
| `maxComments` | integer | 20 | Maximum number of comment/reply rows requested per video. |
| `maxRetries` | integer | 3 | Maximum retries for transient HTTP blocks, rate limits, network errors, and Bilibili risk-control responses. |
| `maxResultsScope` | string | "primary" | primary preserves requested discovery video count; global preserves legacy combined-row limit. |
| `maxOutputRows` | integer | 10000 | Additional safety cap including optional rows. Reaching it may truncate enrichment; charge budget can stop earlier. |

#### Monitoring and state

| Field | Type | Default | Meaning |
|---|---|---|---|
| `deltaMode` | boolean | false | State is isolated by deltaStateKey and persisted across runs in the named bilibili-delta-state store. Use a separate key per workflow and avoid overlapping runs with the same key. |
| `deltaStateKey` | string | "default" | Namespace used to isolate persisted delta-mode history between independent monitors. |

#### Compatibility and transformations

| Field | Type | Default | Meaning |
|---|---|---|---|
| `outputSchema` | string | "extended" | extended adds coverage/warnings; zhorex-strict removes extension fields for easier migration. |

#### Connection and advanced settings

| Field | Type | Default | Meaning |
|---|---|---|---|
| `proxyConfiguration` | object | {"useApifyProxy": false} | Direct HTTP is the default. Enable Apify Proxy if your network is rate-limited. |
| `requestConcurrency` | integer | 5 | Maximum number of independent target requests processed concurrently. |

#### Additional compatibility options

| Field | Type | Default | Meaning |
|---|---|---|---|
| `zhorexInput` | object | Not set | Paste the complete competitor input JSON here to preserve its field types and defaults. Put all options inside this object. This is optional; normal native inputs remain available. |
| `sianInput` | object | Not set | Paste the complete competitor input JSON here to preserve its field types and defaults. Put all options inside this object. This is optional; normal native inputs remain available. |

### Output reference

The table describes native fields; fields can be absent or null when the source does not provide them. Error rows and selected compatibility profiles have different shapes. Nested objects remain structured in JSON; CSV exports may serialize them.

| Field | Type | Meaning |
|---|---|---|
| `type` | string | Result kind such as video, comment, danmaku, user, relation, caption, transcript, live, or error. |
| `bvid` | string | Bilibili video identifier when the row belongs to a video. |
| `aid` | integer | Numeric Bilibili archive ID when available. |
| `title` | string | Video or live-room title when applicable. |
| `url` | string | Canonical public URL for the result when available. |
| `authorName` | string | Public creator name for video/comment rows when available. |
| `authorMid` | integer | Numeric Bilibili creator ID for video/comment rows when available. |
| `viewCount` | \['integer', 'null'] | Public video view count when supplied by the source endpoint. |
| `text` | string | Comment, danmaku, or transcript text depending on the row type. |
| `available` | boolean | For optional source data such as captions/transcripts, whether the public source exposed the requested data. |
| `notAvailableReason` | string | Why optional public data was unavailable, for example login\_required\_by\_source or no\_public\_track. |
| `sourceRequiresLogin` | boolean | Whether Bilibili explicitly indicated that the requested optional source data requires a logged-in source session. |
| `coverage` | string | Completeness assessment for this row: complete, partial, best\_effort, rate\_limited, or not\_available. |
| `warnings` | array | Machine-readable-adjacent human warnings explaining fallbacks, truncation, or source limitations. |
| `sourceMode` | string | Actor mode that produced this row. |
| `retrievalMethod` | string | Public retrieval path used to obtain this row, including fallback paths when applicable. |
| `errorCode` | string | Structured Actor/Bilibili error classification for error rows. |
| `scrapedAt` | string | UTC ISO-8601 time at which the row was produced. |
| `missingFields` | array | Fields unavailable in exact-search detail fallback are null, never fabricated zero counts. |
| `catalogCountGap` | \['integer', 'null'] | Reported total minus unique observed source IDs, clamped at zero; not verified missing videos. |

### API and automation

The **API** tab provides snippets for this Actor. For scheduled or larger collections, start a run asynchronously and poll its status instead of holding a synchronous request open. Keep your API token in an environment variable.

```python
import os, time, requests

base = "https://api.apify.com/v2"
headers = {"Authorization": "Bearer " + os.environ["APIFY_TOKEN"]}
actor_input = {'mode': 'popular', 'maxResults': 5}
response = requests.post(
    base + "/acts/HcxOZArmyg6ZyjOBJ/runs",
    headers=headers, json=actor_input, timeout=30,
)
response.raise_for_status()
run = response.json()["data"]
for _ in range(720):
    if run["status"] not in ("READY", "RUNNING", "TIMING-OUT", "ABORTING"):
        break
    time.sleep(5)
    response = requests.get(base + "/actor-runs/" + run["id"], headers=headers, timeout=30)
    response.raise_for_status()
    run = response.json()["data"]
else:
    raise TimeoutError("Polling ended; inspect the existing run before starting another.")
if run["status"] != "SUCCEEDED":
    raise RuntimeError(run.get("statusMessage", run["status"]))
response = requests.get(
    base + "/datasets/" + run["defaultDatasetId"] + "/items",
    headers=headers, params={"format": "json", "limit": 1000, "offset": 0}, timeout=30,
)
response.raise_for_status()
rows = response.json()
print(rows)  # Paginate with offset for larger datasets; inspect per-row coverage.
```

#### Scheduled monitoring and integrations

1. Save a working input as an Apify Task.
2. Attach a Schedule in your timezone; keep runs sharing an incremental state key sequential.
3. Add a successful-run webhook or connect your downstream workflow to the dataset export/API.
4. Inspect missing/partial data before sending alerts or treating absence as removal.

Use the platform Integrations/API options to connect external workflows such as Make, n8n or a data warehouse. An external sentiment or summarization step is separate from this Actor and may have its own charges. The platform also supports Actor tools through [Apify MCP](https://docs.apify.com/platform/integrations/mcp); availability and client setup depend on your integration.

### FAQ

#### Do users need to use the developer’s Bilibili account?

No shared personal account is promised. Public collection paths are used; source-restricted fields are reported as unavailable or partial.

#### Does this guarantee complete subtitles?

No. Caption and transcript modes depend on source availability; full subtitles are not a guaranteed product feature.

#### What is a danmaku profile?

It summarizes a video’s retrieved timed reactions into a profile. It is billed per delivered profile, separately from a video row.

#### Can I export without writing code?

Yes. Run from the Input form, open the dataset and use the export controls for JSON or CSV. Select your preferred output profile before running when migrating an integration.

#### Does a successful run guarantee every field?

No. Inspect coverage, warnings and source-specific status fields. Optional enrichment may be missing even when usable rows were delivered.

### Troubleshooting

| Symptom | What to check |
|---|---|
| Empty dataset | Validate the target, source availability and filters; try the small quick-start input. |
| Fewer rows than requested | Check source limits, pagination and filtering. Increasing a cap cannot create unavailable source records. |
| Partial fields | Inspect coverage/warnings and the relevant source or enrichment status. |
| Access or throttling errors | Check the run log and documented proxy configuration; retry at a lower request volume. |
| Migration mismatch | Check the explicit input/output profile and technical field mapping below. |
| Unexpected bill | Separate result events from platform resources; inspect enrichment, result caps and the Pricing tab. |

### Technical reference

#### Supported modes

| Mode | Input | Result |
|---|---|---|
| `search` | `searchQuery` | Video rows |
| `video_detail` | `videoUrls` / `bvid` | Full video metadata |
| `video_comments` | `videoUrls` / `bvid` | Comment rows, optional replies |
| `popular` | optional `category` | Popular video rows |
| `ranking` | optional `category` | Ranking video rows |
| `user_profile` | `userIds` / `userId` | Creator profile rows |
| `user_relation_stats` | `userIds` / `userId` | Follower/following rows |
| `user_videos` | `userIds` / `userId` | Creator upload rows; coverage is explicit |
| `video_danmaku` | video target or `cid` | Raw danmaku rows |
| `danmaku_profile` | video target or `cid` | One aggregate reaction profile per video |
| `video_caption` | video target | Native subtitle metadata |
| `video_transcript` | video target | Native subtitle text when available |
| `live_info` | `liveRoomIds` / `roomId` | Public live room state |

#### Quick start

Search:

```json
{
  "mode": "search",
  "searchQuery": "人工智能教程",
  "sortOrder": "pubdate",
  "maxResults": 50
}
```

Video details:

```json
{
  "mode": "video_detail",
  "videoUrls": ["BV1rpWjevEip"]
}
```

Comments with replies:

```json
{
  "mode": "video_comments",
  "videoUrls": ["BV1rpWjevEip"],
  "maxComments": 100,
  "includeReplies": true
}
```

SIAN-style input is accepted too:

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

#### Migration compatibility

The canonical API intentionally keeps familiar fields such as `mode`, `searchQuery`, `videoUrls`, `userIds`, `maxResults`, `sortOrder`, `includeComments`, `includeReplies` and `includeDanmaku`.

By default, `maxResults` limits primary discovery videos. Optional comments, danmaku profiles, creators and transcripts add rows without reducing the requested video count. `maxOutputRows` and the Apify charge budget cap total delivery. Set `maxResultsScope="global"` to restore the legacy shared row budget, which reserves enrichment slots by reducing the initial discovery batch.

For multi-target modes that can emit many rows per target (`user_videos`, comments, raw danmaku, captions, transcripts), the remaining global row budget is distributed across the remaining targets and reallocated when an earlier target returns fewer rows. A single prolific creator or video therefore cannot silently starve the rest of a batch.

Set:

```json
{"outputSchema": "zhorex-strict"}
```

to suppress extension fields on documented video/comment rows. This helps pipelines that reject unknown JSON properties.

Strict video output preserves `authorFace` (the creator avatar URL) when present in the source row. Comment avatars remain in `authorAvatar`; missing video avatars are not fabricated.

The default `extended` schema adds:

```json
{
  "schemaVersion": "1.0",
  "sourceMode": "video_comments",
  "coverage": "complete",
  "warnings": [],
  "retrievalMethod": "public_http"
}
```

`coverage` can be `complete`, `partial`, `best_effort`, `rate_limited`, or `not_available`.

#### Rate limits and proxies

The Actor uses public Bilibili HTTP endpoints. Direct access is the default. Bilibili can return HTTP `412`, API `-352`, or `-799` under risk control, especially during deeper pagination.

The client includes request pacing, exponential retry and optional Apify Proxy sessions. Enable a proxy in the standard `proxyConfiguration` input if your environment is blocked.

Video-bound modes resolve CID/AID separately from full video detail: comments use `/x/player/pagelist` and `/x/player/v2`; danmaku/caption modes use `/x/player/pagelist`. Source restrictions can still prevent retrieval.

`video_detail` itself still prefers the full `/x/web-interface/view` source. If both full-detail APIs are blocked, the Actor performs an exact BVID/AID search, verifies the returned ID, enriches it with `/x/player/pagelist`, and returns that row as `coverage: best_effort` with `retrievalMethod: public_exact_search_fallback`. This is a deliberate downgrade rather than a false error or a false claim of completeness.

`user_videos` attempts the WBI creator catalog, then public media-list, dynamic-feed and exact-MID creator-name search fallbacks. Partial catalog results can trigger supplements. Fallback rows remain `coverage: best_effort`; a complete creator archive is not guaranteed.

#### Comments

Comment coverage depends strongly on Bilibili's response for the caller's egress IP. The Actor first tries the current WBI cursor API, then falls back to the legacy public comment endpoint when necessary. It deduplicates comment IDs and exposes `sourceReportedCommentCount`, `returnedCommentCount`, `coverageRatio`, and `retrievalMethod` when the source provides a total. If the source exposes only top/pinned comments, those rows remain usable but are explicitly marked `coverage: partial`.

A requested comment cap below the source-reported total remains partial coverage even when every requested row is returned.

#### Danmaku

`video_danmaku` returns the public XML danmaku payload as individual rows. `danmaku_profile` reduces the same public payload into count, unique senders, per-minute rate, peak minute and an evenly spread text sample.

#### Native transcripts

`video_caption` returns subtitle metadata/URLs when Bilibili exposes them publicly. `video_transcript` fetches those native subtitle JSON files and produces joined text plus timestamped segments. When the anonymous player API exposes no subtitle track, the Actor returns a status row with `available: false` and `coverage: not_available` instead of pretending the scraper failed. If Bilibili explicitly reports `need_login_subtitle`, the row also carries `notAvailableReason: login_required_by_source` and `sourceRequiresLogin: true`. These unavailable status rows are not charged through a custom pay-per-event result event. The GA Actor intentionally does not request a user's Bilibili session cookie and does not invent an ASR transcript when native subtitles are unavailable.

#### Run success vs. data completeness

A successful Actor run only means the requested workflow executed normally. It does not imply that Bilibili exposed every row that exists on the website. Extended rows therefore carry an explicit completeness signal:

| Coverage | Meaning |
|---|---|
| `complete` | The source endpoint returned the requested object/set without a known truncation signal. |
| `partial` | The source reported or strongly indicated more data than was returned. |
| `best_effort` | A public fallback supplied useful rows, but it is not a guaranteed complete archive. |
| `rate_limited` | Bilibili risk control prevented full retrieval. |
| `not_available` | The optional public data does not exist or was not exposed, for example a video with no public native subtitle track. |

The run-level `OUTPUT` record separately reports `partialRows`, `unavailableRows`, `errorRows`, HTTP request/retry counts, and the number of rows pushed to the dataset.

Run summary status is also explicit:

- `succeeded`: no known coverage limitation or error was observed.
- `succeeded_with_limited_coverage`: the run completed but one or more rows are partial, best-effort, or unavailable.
- `succeeded_with_errors`: some targets failed while other targets still produced data.
- `failed`: every produced row is an error or a top-level mode failure occurred.
- `budget_limit_reached`: Apify stopped additional charged rows at the configured event budget.

#### Delta mode

For `search`, `popular` and `ranking`, set:

```json
{
  "deltaMode": true,
  "deltaStateKey": "my-monitor"
}
```

Delivered video IDs are retained in the named key-value store `bilibili-delta-state`; later runs with the same scope return unseen videos. See incremental state below.

#### Current public-data limitations

- Creator upload catalogs are one of Bilibili's most aggressively risk-controlled public surfaces. `user_videos` therefore treats fallback results as `best_effort` and verifies the creator MID before returning a discovered upload.
- Full-detail sources can be blocked. Exact-ID search fallbacks remain `best_effort`; unavailable deep fields remain null with missing-field diagnostics and no full-detail custom charge.
- Anonymous/datacenter comment access can expose only a tiny set of top or pinned comments even when the video reports a much larger reply count. The Actor reports the observed coverage instead of manufacturing completeness.
- Native captions/transcripts are returned only when Bilibili exposes a subtitle track to the anonymous public player API. If Bilibili marks subtitle metadata as login-required, the output says so explicitly rather than asking for or silently depending on a Bilibili account cookie.
- Optional proxies do not guarantee access or improve every source; direct access remains the default.

#### Data scope

This Actor is built for publicly accessible Bilibili data. Users are responsible for using exported data in accordance with applicable law and the source platform's terms.

##### Incremental state

Delta mode persists delivered video IDs in the named `bilibili-delta-state` key-value store across runs. Use a distinct `deltaStateKey` for each query/filter workflow and do not overlap runs sharing the same key. State is committed after successful delivery, so budget-excluded rows remain eligible on the next run. A crash between delivery and state commit may repeat rows; consumers should deduplicate by BVID. The latest 20,000 IDs are retained per key.

##### Missing-field semantics

Exact-search detail fallback now returns null for unavailable engagement counts and lists them in missingFields. Consumers must accept null; this corrects previous unknown-as-zero values. Complete detail still depends on source availability and is not guaranteed. Extended video output includes authorFace when provided by the source.

##### Discovery completeness correction

maxResults now counts primary discovery videos by default. includeComments/includeDanmaku/includeCreator/includeTranscript add output rows without reserving slots by reducing the video request. maxOutputRows (default and maximum 10000) and the Apify charge budget remain total caps. Extra paid enrichment can increase the bill. Set maxResultsScope="global" to retain the previous combined-row limit. Source unavailability may still prevent enrichment.

The schema no longer injects a default mode that conflicts with operation aliases. Creator pagination keeps page size fixed across pages; profile enrichment failure no longer discards already recovered video rows.

All-error runs now finish as platform FAILED after saving diagnostic rows and OUTPUT. Limited-coverage non-error records are still explicitly marked and are not a claim of full task completion.

#### Creator catalog recovery

If WBI creator search is unavailable, the public media-list endpoint supplies creator uploads with cursor pagination. Every author MID is checked; rows with a different primary author are excluded and counted in catalogExcludedOtherAuthors (source lists may include collaborations). Source coin/share/like counts and video part IDs are preserved; missing statistics remain null. catalogTotalCount and catalogHasMore describe the source response, not a guarantee that all uploads were fetched. Pagination failures after successful pages retain partial results with warnings.

When an exhausted public creator media list reports more videos than the unique
source IDs observed, `catalogCountGap` records that discrepancy. An exhaustion
flag alone no longer disables the existing exact-author dynamic/search fallbacks
in this case. The gap is a source-count discrepancy, not proof of that many missing
public videos. Supplemental sources may still return nothing new. Source warnings
and best-effort coverage remain; complete creator-history recall is not promised.

##### Optional sentiment scoring

Enable `sentimentAnalysis` to add `sentiment: {polarity, score, method}` to video and comment rows, including strict compatibility output. SnowNLP 0.12.3 runs locally with no third-party API fee; allocate at least 512 MB. Scores range from -1 to +1; the neutral band is \[-0.1, 0.1]. This is a heuristic trained primarily on product reviews, not a claim of validated Bilibili sentiment accuracy. See [the model documentation](https://github.com/isnowfy/snownlp).

Non-Chinese or empty text uses `method: no_chinese_text`. Model failures have null scores and a warning. Exceptionally long inputs are scored on the first 8,000 characters with `sentimentInputTruncated: true`; the scraped title/description/comment remains complete. Existing runs keep this feature disabled by default.

### Support

Open an issue from this Actor’s **Issues** tab with the run ID, expected result and a redacted input. Do not include tokens, cookies or private credentials. Include the output profile and affected field when reporting a migration mismatch.

### Presentation update

The current listing adds workflow examples, grouped input documentation, output-field explanations and plan-based result discounts. Source-specific limitations above still apply. This is an independent tool and is not affiliated with the source platform.

# Actor input Schema

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

Canonical mode. Leave empty when using the SIAN-compatible operation field.

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

Optional compatibility alias: searchVideo, videoDetail, videoComments, userDetail, userRelationStat, userVideos, videoDanmu, videoCaption.

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

Keyword used in search mode.

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

SIAN-compatible alias for searchQuery.

## `autoLocalize` (type: `boolean`):

Also search a small set of common Chinese brand-name aliases when available.

## `searchAliases` (type: `array`):

Extra terms to search and merge with the primary keyword.

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

YYYY-MM-DD

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

YYYY-MM-DD

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

One or more Bilibili video URLs, BVIDs, or numeric AIDs.

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

Single BVID compatibility alias for video modes.

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

Single numeric AID compatibility alias. Caption/transcript can also use aid together with cid.

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

Single video CID, used directly by danmaku/caption/transcript modes when applicable.

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

One or more Bilibili creator MIDs.

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

Single creator MID compatibility alias.

## `liveRoomIds` (type: `array`):

One or more Bilibili live room IDs or live-room URLs.

## `roomId` (type: `string`):

Single live room ID compatibility alias.

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

Category filter for popular and ranking modes.

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

For discovery modes, append public comment rows for discovered videos while respecting the global maxResults row cap. The Actor reserves enrichment capacity before discovery so this flag is not a silent no-op when discovery could otherwise fill the cap.

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

When scraping comments, expand available child reply chains.

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

For discovery modes, append one aggregate danmaku profile per discovered video.

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

Maximum number of representative danmaku texts kept in a danmaku profile.

## `includeCreator` (type: `boolean`):

For discovery modes, append public creator profile rows for creators in the video results.

## `includeTranscript` (type: `boolean`):

For discovery modes, append native transcript rows when Bilibili exposes public subtitle tracks.

## `enrichDetails` (type: `boolean`):

More complete engagement fields at the cost of additional requests.

## `requestDelayMillis` (type: `integer`):

Minimum spacing in milliseconds between HTTP request starts across the client.

## `sentimentAnalysis` (type: `boolean`):

Local SnowNLP polarity and -1 to +1 score for comments and video titles/descriptions. Use at least 512 MB memory. No external API fee. This heuristic is not a validated accuracy guarantee; non-Chinese text is tagged no\_chinese\_text.

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

Sort video search results by relevance, views, publish time, danmaku, favorites, or score.

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

Limit search results by Bilibili duration bucket.

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

Preferred public comment ordering.

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

Primary result limit. In discovery modes, optional enrichment adds rows without reducing requested videos. maxOutputRows and the Apify charge budget remain hard caps. Set maxResultsScope=global for legacy total-row semantics.

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

SIAN-compatible page cap. maxResults remains the hard row cap.

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

Maximum number of comment/reply rows requested per video.

## `maxRetries` (type: `integer`):

Maximum retries for transient HTTP blocks, rate limits, network errors, and Bilibili risk-control responses.

## `maxResultsScope` (type: `string`):

primary preserves requested discovery video count; global preserves legacy combined-row limit.

## `maxOutputRows` (type: `integer`):

Additional safety cap including optional rows. Reaching it may truncate enrichment; charge budget can stop earlier.

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

State is isolated by deltaStateKey and persisted across runs in the named bilibili-delta-state store. Use a separate key per workflow and avoid overlapping runs with the same key.

## `deltaStateKey` (type: `string`):

Namespace used to isolate persisted delta-mode history between independent monitors.

## `outputSchema` (type: `string`):

extended adds coverage/warnings; zhorex-strict removes extension fields for easier migration.

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

Direct HTTP is the default. Enable Apify Proxy if your network is rate-limited.

## `requestConcurrency` (type: `integer`):

Maximum number of independent target requests processed concurrently.

## `zhorexInput` (type: `object`):

Paste the complete competitor input JSON here to preserve its field types and defaults. Put all options inside this object. This is optional; normal native inputs remain available.

## `sianInput` (type: `object`):

Paste the complete competitor input JSON here to preserve its field types and defaults. Put all options inside this object. This is optional; normal native inputs remain available.

## Actor input object example

```json
{
  "mode": "popular",
  "autoLocalize": true,
  "searchAliases": [],
  "videoUrls": [],
  "userIds": [],
  "liveRoomIds": [],
  "category": "all",
  "includeComments": false,
  "includeReplies": false,
  "includeDanmaku": false,
  "danmakuSampleSize": 25,
  "includeCreator": false,
  "includeTranscript": false,
  "enrichDetails": false,
  "requestDelayMillis": 120,
  "sentimentAnalysis": false,
  "sortOrder": "totalrank",
  "durationFilter": "any",
  "sortComments": "hot",
  "maxResults": 100,
  "maxComments": 20,
  "maxRetries": 3,
  "maxResultsScope": "primary",
  "maxOutputRows": 10000,
  "deltaMode": false,
  "deltaStateKey": "default",
  "outputSchema": "extended",
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "requestConcurrency": 5
}
```

# Actor output Schema

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

All video, comment, danmaku, creator, caption, transcript, live, status, and error rows produced by the run.

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

Run-level counts for produced, partial, unavailable, and error rows plus HTTP request/retry telemetry.

# 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"
};

// Run the Actor and wait for it to finish
const run = await client.actor("peerless_columbine/bilibili-all-in-one-scraper-api").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" }

# Run the Actor and wait for it to finish
run = client.actor("peerless_columbine/bilibili-all-in-one-scraper-api").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"
}' |
apify call peerless_columbine/bilibili-all-in-one-scraper-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,peerless_columbine/bilibili-all-in-one-scraper-api"
        }
    }
}

```

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/HcxOZArmyg6ZyjOBJ/builds/3JUw2wKn0umBI3edP/openapi.json
