Skip to content

feat(pixiv): add Pixiv adapter #403

Merged
jackwener merged 13 commits intojackwener:mainfrom
crrow:feat/pixiv-adapter
Mar 25, 2026
Merged

feat(pixiv): add Pixiv adapter #403
jackwener merged 13 commits intojackwener:mainfrom
crrow:feat/pixiv-adapter

Conversation

@crrow
Copy link
Copy Markdown
Contributor

@crrow crrow commented Mar 25, 2026

Description

Add Pixiv (pixiv.net) adapter with 6 commands for browsing rankings, searching illustrations, viewing artist profiles, listing works, viewing details, and downloading original-quality images.

All commands use the COOKIE strategy, reusing Chrome's logged-in Pixiv session via Browser Bridge. YAML adapters handle simple API fetches (ranking, detail, user), while TypeScript adapters handle complex logic (search with pagination, illusts with two-step fetch, download with Referer header).

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 🌐 New site adapter
  • 📝 Documentation
  • ♻️ Refactor
  • 🔧 CI / build / tooling

Checklist

  • I ran the checks relevant to this PR
  • I updated tests or docs if needed
  • I included output or screenshots when useful

Documentation (if adding/modifying an adapter)

  • Added doc page under docs/adapters/ (if new adapter)
  • Updated docs/adapters/index.md table (if new adapter)
  • Updated sidebar in docs/.vitepress/config.mts (if new adapter)
  • Updated README.md / README.zh-CN.md when command discoverability changed
  • Used positional args for the command's primary subject unless a named flag is clearly better
  • Normalized expected adapter failures to CliError subclasses instead of raw Error

Commands

Command Description Strategy Type
pixiv ranking Daily/weekly/monthly illustration rankings COOKIE YAML
pixiv search <query> Search illustrations by keyword/tag COOKIE TS
pixiv user <uid> View artist profile info COOKIE YAML
pixiv illusts <user-id> List illustrations by artist COOKIE TS
pixiv detail <id> View illustration details (tags, stats, url) COOKIE YAML
pixiv download <illust-id> Download original-quality images COOKIE TS

Screenshots / Output

$ opencli pixiv ranking --limit 3 -f json
[
  { "rank": 1, "title": "魔女会喫茶", "author": "torino", "illust_id": 142584954, "pages": "1", "bookmarks": 2649 },
  { "rank": 2, "title": "星街すいせい", "author": "Mika Pikazo", "illust_id": 142630180, "pages": "2", "bookmarks": 3770 },
  { "rank": 3, "title": "悪人顔王子、第一王子と出会う", "author": "魔木", "illust_id": 142630445, "pages": "12", "bookmarks": 3339 }
]

$ opencli pixiv download 142584954
  pixiv/download
┌───────┬───────┬─────────┬────────┐
│ Index │ Type  │ Status  │ Size   │
├───────┼───────┼─────────┼────────┤
│ 1     │ image │ success │ 2.7 MB │
└───────┴───────┴─────────┴────────┘

Verification

# Unit + adapter tests (45 tests, all passing)
npx vitest run --project adapter

# Type check
npx tsc --noEmit

Technical Notes

  • Ranking API: Uses /ranking.php?format=json (not /ajax/ranking which returns 404)
  • Download: Pixiv CDN (i.pximg.net) requires Referer: https://www.pixiv.net/ — handled via httpDownload directly rather than downloadMedia to pass custom headers
  • Error handling: Differentiates 401/403 (auth), 404 (not found), and other HTTP errors
  • Security: All user inputs in page.evaluate are serialized via JSON.stringify to prevent code injection
  • Test utilities: Introduces shared test-utils.ts with minimal page mock factory to reduce duplication across test files

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Pixiv browser adapter with commands: ranking, search, user profile lookup, illustration listing, detail view, and download functionality
    • Download support includes original-quality images and multi-page works
  • Documentation

    • Added comprehensive Pixiv adapter documentation with command references and CLI examples
    • Updated README files to document Pixiv support and available commands
  • Tests

    • Added test suites for Pixiv commands and E2E authentication tests

crrow and others added 13 commits March 25, 2026 10:57
Add support for Pixiv (pixiv.net) with the following commands:
- ranking: daily/weekly/monthly illustration rankings
- search: search illustrations by keyword/tag
- user: view artist profile info
- illusts: list illustrations by artist
- detail: view illustration details (tags, stats)
- download: download original-quality images

All commands use COOKIE strategy to reuse Chrome's logged-in session.
YAML adapters for simple API fetches (ranking, detail, user), TypeScript
for complex logic (search, illusts, download with Referer header).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- search.test.ts: auth error, result parsing, limit, empty results (4 tests)
- illusts.test.ts: auth error, empty user, two-step fetch, limit (4 tests)
- download.test.ts: auth error, no images, Referer header, partial failure (4 tests)
- Add pixiv to vitest adapter project include list
- Add 5 pixiv commands to E2E browser-auth graceful failure tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ranking: use /ranking.php?format=json (not /ajax/ranking which 404s)
- ranking: fix JSON path from data.body.contents to data.contents
- user/detail: rename hyphenated args (user-id → uid, illust-id → id)
  to fix YAML template evaluation (dot access doesn't support hyphens)

All 6 commands verified working against live Pixiv API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…uate

Address CodeRabbit review: all user inputs (query, userId, illustId,
idsParam) passed to page.evaluate are now serialized via JSON.stringify
instead of direct string interpolation, preventing code injection in
browser context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ranking.yaml: add | json filter to page/limit args for defense-in-depth
- user.yaml: guard illusts/manga/novels with typeof check for robustness
- Extract shared createPageMock to test-utils.ts, deduplicate across 3 test files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- test-utils.ts: slim down to minimal mock (goto, evaluate, getCookies)
  with overrides support, matching upstream's pragmatic mock style
- Add missing download command to E2E browser-auth graceful failure tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- detail.yaml: add url to columns to match description mentioning "URLs"
- All adapters: differentiate HTTP errors — 401/403 → AuthRequiredError,
  404 → "not found", others → generic "request failed (HTTP N)"
- Tests: use beforeAll to cache registry lookup, avoiding repeated reads
  from global singleton
- Tests: assert error type (AuthRequiredError) not just message content
- Tests: add dedicated test cases for non-auth errors (500) and 404

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add pixiv.md documentation page under docs/adapters/browser/
- Update docs/adapters/index.md with pixiv entry
- Add Pixiv to sidebar in docs/.vitepress/config.mts
- Update README.md and README.zh-CN.md adapter tables
- Add pixiv to download support tables in both READMEs

Completes the documentation checklist for the pixiv adapter PR.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use CommandExecutionError instead of raw Error for HTTP failures
- Add page.goto() before page.evaluate() to establish browser context
- Fix search keyword double-encoding in URL construction
- Fix ranking.yaml using rating_count instead of illust_bookmark_count
- Throw on batch detail fetch failure instead of silent empty return
- Add beforeEach mock reset in download tests
- Add novels column to user.yaml output

Ensures pixiv adapter follows upstream CliError conventions and handles
edge cases correctly before submitting to upstream.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace technical Referer header detail with user-facing description
- Describe what users care about: original quality and multi-page support

Technical details belong in code comments, not user-facing docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add ranking mode examples including R18 variants
- Add search filter examples (mode, order, pagination)
- Organize examples by command category for readability

Users need to know available options without reading source code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Validate illust-id is numeric to prevent path traversal
- Move URL parsing inside per-item try block for graceful error handling
- Add auth error handling for batch detail request (consistent with step 1)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on & batch support

- Create utils.ts with pixivFetch() for unified navigate + fetch + error handling
- Refactor search.ts, illusts.ts, download.ts to use pixivFetch (DRY)
- Add user-id/illust-id numeric validation in TS adapters
- Add batch pagination in illusts.ts for limit > 48 (Pixiv server limit)
- Add comment explaining Pixiv search API dual keyword requirement
- Update tests: new invalid-ID test cases, aligned mock format with pixivFetch
@jackwener jackwener merged commit d36a43e into jackwener:main Mar 25, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants