Skip to main content

jmcpy

禁漫天堂的 Python SDK。

  • 同步 / 异步双份 API,接口逐字对应
  • 两种客户端实现:移动端接口(请求签名 + 响应解密,字段最全)与网页端接口 (补齐移动端没有的分类副分类搜索);门面客户端按能力自动路由
  • 自动重试 + 多端点切换:同端点退避重试、失败换线路,两种模式可配;端点池支持 远端自动发现与本地缓存
  • 绕过反爬:默认用 curl-cffi 伪装浏览器指纹,可回退 httpx
  • 可选登录:凭据加密保存在用户配置目录,主密钥交给操作系统钥匙串;不登录也能用
  • 图片下载与分块还原,交付为 bytes / base64 / 文件路径 / PDF

本项目仅供学习网络协议与 Python 工程实践使用。请遵守所在地法律法规以及目标站点的服务条款, 不要用于商业用途或大规模抓取。

安装

uv add jmcpy              # 或 pip install jmcpy
uv add "jmcpy[keyring]"   # 额外启用操作系统钥匙串保存会话主密钥
uv add "jmcpy[httpx]"     # 额外启用 httpx 传输后端(默认用 curl-cffi)

要求 Python 3.11 及以上。

快速开始

from jmcpy import Client, ExportFormat

with Client() as client:
    page = client.search("关键词", page=1)
    print(page.total, page.page_count)

    book = client.get_book("JM1114751")  # 车号也接受 int、"1114751"、本子 URL
    print(book.title, len(book.chapters))

    chapter = client.get_chapter(book.chapters[0].chapter_id)
    print(len(chapter), chapter.pictures[:3])  # 章节里的图片文件名

    result = client.download(chapter, output=ExportFormat.PDF, dest="./downloads")
    print(result.pdf, result.ok)

异步版本逐字对应,只是加 await:

import asyncio

from jmcpy import AsyncClient, ExportFormat


async def main() -> None:
    async with AsyncClient() as client:
        page = await client.search("关键词")
        book = await client.get_book(page.items[0].book_id)
        chapter = await client.get_chapter(book.chapters[0].chapter_id)
        await client.download(chapter, output=ExportFormat.PATH, dest="./downloads")


asyncio.run(main())

搜索

from jmcpy import Genre, RankingSpan, SearchTarget, SortBy, SubGenre, TimeRange

with Client() as client:
    client.search("MANA")  # 站内搜索
    client.search("MANA", target=SearchTarget.AUTHOR)  # 按作者
    client.search("无修正", sort=SortBy.VIEWS, time_range=TimeRange.WEEK)
    client.search("MANA", genre=Genre.DOUJIN)  # 限定大分类

    # 副分类只有网页端支持,门面会自动路由;若当前网络访问不了网页端会抛 ChallengeBlocked
    client.search("MANA", genre=Genre.DOUJIN, sub_genre=SubGenre.CG)

    client.browse(genre=Genre.HANMAN, sort=SortBy.LIKES, time_range=TimeRange.MONTH)
    client.ranking(RankingSpan.DAY)  # 日/周/月排行

评论

with Client() as client:
    feed = client.get_comments(1114751, page=1)
    print(feed.total, feed.page_count)

    for comment in feed:
        print(comment.display_name, "剧透" if comment.is_spoiler else "", comment.content)
        for reply in comment.replies:  # 回评(可多层)
            print("  ", reply.display_name, reply.content)

    for feed in client.iter_comments(1114751, limit=3):  # 逐页遍历
        print(feed.page, len(feed))

登录(可选)

不登录也能使用除鉴权接口之外的全部功能。登录后凭据会保存在用户配置目录:

平台 路径
Linux ~/.config/jmcpy/session.json
macOS ~/Library/Application Support/jmcpy/session.json
Windows %LOCALAPPDATA%\jmcpy\session.json

文件用 Fernet 加密,主密钥存放在操作系统钥匙串;钥匙串不可用时降级为 0600 权限的 明文文件并给出 warning。可用 JMCPY_HOME 或 Settings(home=...) 改到别处。

with Client() as client:
    client.login("用户名", "密码")  # remember=False 则只留在内存里
    print(client.account().username)

# 下次构造客户端时会自动恢复登录态(可用 restore_session=False 关闭)
with Client() as client:
    print(client.is_logged_in())

下载与输出格式

from jmcpy import ExportFormat

with Client() as client:
    chapter = client.get_chapter(1114751)

    images = client.download(chapter, output=ExportFormat.BYTES)  # list[bytes]
    texts = client.download(chapter, output=ExportFormat.BASE64)  # list[str]
    paths = client.download(chapter, output=ExportFormat.PATH, dest="./out")  # list[Path]
    pdf = client.download(chapter, output=ExportFormat.PDF, dest="./out")  # Path

    for artifact in pdf:
        print(artifact.index, artifact.suffix, artifact.decoded, artifact.size)
    print(pdf.pdf, len(pdf.failures))

细节见 docs/downloading.md:并发、是否还原、覆盖策略、质量、 PDF 分辨率、失败收集与进度回调都在那里。

配置

from jmcpy import Client, RetryMode, Settings

settings = Settings(
    timeout=20.0,  # 接口超时(秒)
    image_timeout=60.0,  # 图片超时(秒)
    retry_times=3,  # 每个端点的重试次数
    retry_mode=RetryMode.RETRY_FIRST,
    concurrency=8,  # 图片并发
    proxy="http://127.0.0.1:7890",
)
with Client(settings) as client:
    ...

也可以写配置文件(默认 <配置目录>/config.toml)或用环境变量覆盖:

# ~/.config/jmcpy/config.toml
timeout = 30
retry_mode = "rotate_first"
mobile_endpoints = ["www.cdngwc.cc"]
JMCPY_TIMEOUT=30 JMCPY_PROXY=http://127.0.0.1:7890 python your_script.py

优先级:显式参数 > 环境变量 > 配置文件 > 出厂默认。全部配置项见 docs/configuration.md。

文档

许可

MIT

Metadata

Release files for jmcpy 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jmcpy 0.1.0
File Size Uploaded
jmcpy-0.1.0.tar.gz 123.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jmcpy 0.1.0
File Interpreter ABI Platform
jmcpy-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 205.6 kB

Release files / jmcpy-0.1.0.tar.gz

Download URL jmcpy-0.1.0.tar.gz
Size 123.5 kB
Tags Source
SHA-256 checksum
How to use checksums
9b72563de301bb6b312e0950a3e7423bcf0b72e19c19275e7f83df617db4b2ba
BLAKE2b-256 checksum
How to use checksums
8b7790dc96096cd283eb98d3c68e27eeb95a5c4c8020adc2f581fe14222bf27b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / jmcpy-0.1.0-py3-none-any.whl

Download URL jmcpy-0.1.0-py3-none-any.whl
Size 82.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c3388cc589ca5487046b45c3d94e82e30209428e11be8223084668491fde5456
BLAKE2b-256 checksum
How to use checksums
7ccf4df7134e23df8356cb40217eae43245c7e31a46a805144094afb115c8ef0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page