Skip to main content

微博 API 的纯异步客户端

Project description

weibo-cli

简洁的微博 API 异步客户端。类型安全,基于本地 Playwright profile 复用登录态。

安装

uv pip install -e .
uv run weibo-cli install-browser

install-browser 不再自动安装任何东西,只会打印手动安装提示。你需要自己执行:

uv pip install playwright
PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright uv run playwright install chromium
uv run playwright install-deps

快速开始

首次使用前,先准备本地浏览器会话:

uv run weibo-cli login --cache-dir ~/.weibo-api/cache

登录成功后,正常 API 只读取本地导出的 Cookie:

import asyncio
from weibo_cli import WeiboClient

async def main():
    async with WeiboClient(cache_dir="~/.weibo-api/cache") as client:
        # 获取用户信息
        user = await client.get_user("1749127163")
        print(f"用户: {user.screen_name}")

        # 获取用户微博
        posts = await client.get_user_posts("1749127163", page=1)
        print(f"微博数: {len(posts)}")

        # 获取微博详情
        post = await client.get_post("5226761046462968")
        print(f"内容: {post.text}")

        # 获取评论
        comments = await client.get_post_comments("5226761046462968")
        print(f"评论数: {len(comments)}")

        # 获取好友圈时间线(每次都会先查 allGroups 再解析分组)
        timeline = await client.get_group_timeline("互相关注", count=25)
        print(f"好友圈微博数: {len(timeline)}")

asyncio.run(main())

浏览器会话与缓存目录

  • 默认缓存目录是 ~/.weibo-api/cache
  • 这个目录是单账号、单 profile 的本地真源
  • 调用者如果想手动管理多个账号,直接传不同的 cache_dir 即可
  • 浏览器 profile 存在 cache_dir/profile/
  • 导出的 HTTP Cookie 存在 cache_dir/export/cookie_header.txt
  • 库运行状态和刷新调度存在 cache_dir/state.json
  • 库自己的元数据存在 cache_dir/meta.json

会话生命周期

  • 认证方式改为 Playwright persistent context
  • Cookie 来源是单向的:只从本地 Playwright profile 导出,不接受手工 Cookie 注入
  • 用户手动在浏览器里登录微博,库只负责保存和复用浏览器状态
  • 普通 API 请求只读取本地导出的 Cookie,不会在主请求路径里隐式访问 Hugging Face
  • cookie_ttl 是成功登录/刷新后的固定刷新间隔;普通 API 使用只更新 last_access_at,不会顺延 next_refresh_at
  • 如果 state.jsonnext_refresh_at 到期,请求前会触发一次 Playwright 刷新:打开 weibo.com、等待页面加载、再探测微博 timeline 是否可访问
  • 如果请求过程中遇到登录失效/验证码拦截,读接口会再触发一次 Playwright 刷新探测;如果 profile 已失效,则直接报错,不做自动登录
  • 写接口不会在鉴权失败后自动重放,避免重复写入
  • backup push/pull 会同步完整会话缓存:profile/export/meta.jsonstate.json
  • lock/archive/ 不会同步

常用命令

# 打印 Playwright/Chromium 手工安装提示
uv run weibo-cli install-browser

# 首次手动登录,初始化本地 profile
uv run weibo-cli login --cache-dir ~/.weibo-api/cache

# 复用现有 profile 刷新 Cookie
uv run weibo-cli refresh --cache-dir ~/.weibo-api/cache

# 查看本地缓存状态
uv run weibo-cli status --cache-dir ~/.weibo-api/cache

# 手动备份完整缓存到 Hugging Face Bucket
uv run weibo-cli backup push --cache-dir ~/.weibo-api/cache --token <token>

# 手动从 Hugging Face Bucket 恢复完整缓存
uv run weibo-cli backup pull --cache-dir ~/.weibo-api/cache --token <token>

API

WeiboClient

异步上下文管理器,自动处理连接生命周期。

async with WeiboClient(
    config=None,
    logger=None,
    max_concurrent_requests=4,
    requests_per_interval=10,
    rate_interval_seconds=1.0,
    cache_dir=None,
) as client:
    ...

参数

  • config: WeiboConfig 实例,默认使用标准配置
  • logger: 自定义 logger,默认使用模块 logger
  • max_concurrent_requests: 并发请求上限
  • requests_per_interval: 每时间窗口的请求数上限
  • rate_interval_seconds: 速率限制窗口(秒)
  • rate_limiter: 传入自定义 RateLimiter,覆盖默认策略
  • cache_dir: 浏览器会话缓存目录,默认是 ~/.weibo-api/cache

会话方法

  • await get_cookies() -> str:返回当前导出的 Cookie 头,必要时会触发刷新
  • await refresh_cookies() -> str:强制触发一次 Playwright 刷新并重新导出 Cookie
  • await validate_cookies() -> bool:验证当前导出的浏览器会话是否仍可访问微博 API
  • get_cached_cookies() -> str | None:只读返回当前缓存的 Cookie 头,不触发刷新
  • await get_cookie_snapshot() -> dict[str, float | str | None]:返回当前会话快照信息

业务方法与实际接口

方法 HTTP 接口 返回 说明
get_basic_info() GET /ajax/setting/getBasicInfo BasicInfo 获取当前账号资料设置
get_user(user_id) GET /ajax/profile/info?uid=<user_id> User 获取用户资料
get_user_posts(user_id, page=1) GET /ajax/statuses/mymblog?uid=<user_id>&page=<page> list[Post] 获取用户微博时间线
get_groups() GET /ajax/feed/allGroups list[Group] 获取好友圈/分组列表
get_group_timeline(group, count=25, refresh=4, fast_refresh=1) GET /ajax/feed/groupstimeline list[Post] 获取指定分组时间线
get_post(post_id) GET /ajax/statuses/show?id=<post_id> Post 获取微博详情
get_post_comments(post_id) GET /ajax/statuses/buildComments?...&id=<post_id> list[Comment] 获取微博评论
get_mentions(page=1) GET /ajax/statuses/mentions?page=<page> list[Post] 获取 @我 的微博列表
get_received_comments(page=1) GET /ajax/message/cmt?page=<page> list[Comment] 获取收到的评论
upload_comment_image(image_path) POST https://picupload.weibo.com/interface/upload.php str 上传评论图片并返回 pic_id
reply_comment(post_id, comment_id, content, image_path=None, pic_id=None) POST /ajax/comments/reply CommentActionResult 回复评论,可附图
post_comment(post_id, content, image_path=None, pic_id=None) POST /ajax/comments/create CommentActionResult 发表评论,可附图

Playwright 刷新探针

  • Playwright 刷新会先访问桌面首页(config.api.home_url,默认是 https://weibo.com/
  • 页面加载后,再探测 GET /ajax/statuses/mymblog?uid=1642909335&page=1
  • 只有探针返回 ok=1 且 timeline 非空,才认为当前 profile 仍然有效

WeiboConfig

配置类,控制 HTTP、认证、API 行为。

from weibo_cli import WeiboConfig

# 默认配置
config = WeiboConfig()

# 快速配置(低延迟,低重试)
config = WeiboConfig.create_fast()

# 保守配置(高超时,高重试)
config = WeiboConfig.create_conservative()

配置字段

@dataclass
class WeiboConfig:
    http: HttpConfig       # HTTP 配置
    auth: AuthConfig       # 认证配置
    api: ApiConfig         # API 端点配置

HttpConfig

timeout: float = 10.0                    # 请求超时(秒)
max_retries: int = 3                     # 最大重试次数
base_delay: float = 1.0                  # 基础延迟(秒)
max_delay: float = 60.0                  # 最大延迟(秒)
max_connections: int = 20                # 最大连接数
max_keepalive_connections: int = 5       # 保持活跃连接数

AuthConfig

cookie_ttl: float = 1800.0               # 固定 Cookie 刷新间隔(秒),默认 30 分钟

ApiConfig

base_url: str = "https://weibo.com"
mobile_url: str = "https://m.weibo.cn"
user_agent: str = "Mozilla/5.0 ..."

数据模型

所有模型都基于 Pydantic v2BaseModel,自动完成类型转换、校验与序列化。

User

from weibo_cli.models import User

user = User(
    id=123,
    screen_name="Test User",
    profile_image_url="https://example.com/avatar.jpg",
    followers_count=100,
)

# Pydantic API 同样可用
user_dict = user.model_dump()

Post

from datetime import datetime

from weibo_cli.models import Post, Image, Video

post = Post(
    id=1,
    created_at=datetime.utcnow(),
    text="Hello Weibo",
    user=user,
    images=[Image(id="pic1", thumbnail_url="...", large_url="...", original_url="...")],
    video=Video(duration=10.5, play_count=999),
    reposts_count=1,
    comments_count=2,
    attitudes_count=3,
)

# 每个模型都带有 `raw` 字段,保存原始结构化 payload 的深拷贝快照
print(post.raw)

BasicInfo / Group / CommentActionResult

from weibo_cli import CommentActionResult, Group, WeiboClient

async with WeiboClient(cache_dir="~/.weibo-api/cache") as client:
    info = await client.get_basic_info()
    print(info.screen_name)

    groups: list[Group] = await client.get_groups()
    print(groups[0].name, groups[0].list_id)

    result: CommentActionResult = await client.post_comment("5226761046462968", "Hello")
    if result.comment is not None:
        print(result.comment.id)

    pic_id = await client.upload_comment_image("./comment.gif")
    await client.post_comment("5226761046462968", "Hello with image", pic_id=pic_id)
    await client.post_comment("5226761046462968", "Hello with image", image_path="./comment.gif")

upload_comment_image 使用微博网页端评论图上传接口。实测必需参数是 ent=miniblog 和按图片原始 bytes 计算的 cs=crc32(image_bytes)ori=1 会保留,用于请求原图上传语义。

异常

from weibo_cli.exceptions import (
    WeiboError,      # 基础异常
    AuthError,       # 认证失败
    NetworkError,    # 网络错误
    ParseError,      # 解析错误
)

测试

uv run pytest -v

发布前清理

发布/打包前运行 scripts/prep_release.sh,脚本会:

  • 执行 python -m compileall -q src tests,提前暴露语法错误
  • 清理 __pycache__ 目录,确保工作区干净
bash scripts/prep_release.sh

验证会话导出

执行 weibo-cli refresh 后,可以直接检查本地导出文件:

uv run weibo-cli refresh --cache-dir ~/.weibo-api/cache
cat ~/.weibo-api/cache/export/cookie_header.txt
cat ~/.weibo-api/cache/state.json

如果导出成功,cookie_header.txt 会包含 SUB / SUBP 等微博登录 Cookie,state.json 会记录最近一次刷新、下次刷新和访问时间戳。

# 运行所有测试
uv run pytest -v

# 带覆盖率
uv run pytest --cov -v

架构

WeiboClient              # Facade 入口
├── HttpClient           # HTTP 请求
├── AuthProvider         # 认证材料抽象
├── BrowserSessionManager# Playwright 持久浏览器会话
├── LocalCache           # 本地 cache_dir 真源
├── RetryStrategy        # 重试策略(指数退避)
├── UserParser           # 用户数据解析
├── PostParser           # 微博数据解析
└── CommentParser        # 评论数据解析

设计原则

  • 单一职责:每个类只做一件事
  • 组合优于堆叠:WeiboClient 只是把 HTTP、认证、解析串起来
  • 无全局状态:线程安全
  • 显式优于隐式:所有配置都可见

许可证

GNU Affero General Public License v3.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

weibo_cli-1.0.5.tar.gz (72.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

weibo_cli-1.0.5-py3-none-any.whl (62.2 kB view details)

Uploaded Python 3

File details

Details for the file weibo_cli-1.0.5.tar.gz.

File metadata

  • Download URL: weibo_cli-1.0.5.tar.gz
  • Upload date:
  • Size: 72.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for weibo_cli-1.0.5.tar.gz
Algorithm Hash digest
SHA256 adb0a17663ac710192dfc366bd6008a2e6f315d1cf3fea2748bb0f47c9daa8b3
MD5 884e5ecd52a83105985bb390b743319e
BLAKE2b-256 d57b6bacf59a49529d28f00d66c0db694f6951ffea04c79737e8cd0541e37cbb

See more details on using hashes here.

File details

Details for the file weibo_cli-1.0.5-py3-none-any.whl.

File metadata

  • Download URL: weibo_cli-1.0.5-py3-none-any.whl
  • Upload date:
  • Size: 62.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for weibo_cli-1.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 4b5618b8fc918c087eed4765e09cb7fc7da6e18cfdec313ed96c7d1418805aff
MD5 6d7c1278f5e16c38202fc27fe7a6cfbb
BLAKE2b-256 179c2371d5596d5c45a3ba3535279098b52fecc8fecc0f0c2f377f30ca97c293

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page