示例

本页提供 aioqzone 使用示例。

登录

from aioqzone.api import QrLoginConfig, QrLoginManager
from qqqr.utils.net import ClientAdapter

with ClientAdapter() as client:
    mgr = QrLoginManager(client, config=QrLoginConfig(uin=env.uin))

登录时会自动设置 User-Agent。

from aioqzone.api import UpLoginConfig, UpLoginManager
from qqqr.utils.net import ClientAdapter

with ClientAdapter() as client:
    mgr = UpLoginManager(
        client,
        config=UpLoginConfig.model_validate(
            dict(uin=env.uin, pwd=env.password, fake_ip="8.8.8.8")
        ),
    )

登录时会自动设置 User-Agent。

您也可以禁用自动登录,使用外部 cookie:

import json
from os import environ

from aioqzone.api.login import ConstLoginMan
from qqqr.utils.net import ClientAdapter

with open("your_external_cookie.json") as f:
    cookie = json.load(f)
with ClientAdapter() as client:
    mgr = ConstLoginMan(cookie)

User-Agent 不会自动设置,请记得修改:

from qqqr.utils.net import ClientAdapter
from qqqr.utils.net import use_mobile_ua

with ClientAdapter() as client:
    use_mobile_ua(client)

...

如果希望在自动登录时使用外部 cookie,只需将 cookie 字典赋值给 login manager:

import json
from os import environ

from aioqzone.api.login import QrLoginManager
from qqqr.utils.net import ClientAdapter

with open("your_external_cookie.json") as f:
    cookie = json.load(f)
with ClientAdapter() as client:
    mgr = QrLoginManager(client, config=QrLoginConfig(uin=env.uin))
    mgr.cookie = cookie  # assign external cookie to login manager

从 Login Manager 接收消息

参见

消息

您可以从 QR code login manager 接收二维码图片:

import io

from PIL import Image as image

man = QrLoginManager(client, config=QrLoginConfig(uin=env.uin))
man.qr_fetched.add_impl(
    lambda png, times, qr_renew=False: image.open(io.BytesIO(png)).show() if png else None
)

创建 Qzone H5 API

from aioqzone.api import QzoneH5Api
from aioqzone.api.login import QrLoginManager
from qqqr.utils.net import ClientAdapter

with ClientAdapter() as client:
    mgr = QrLoginManager(client, config=QrLoginConfig(uin=env.uin))
    api = QzoneH5Api(client, mgr)
from aioqzone.api import UpLoginConfig, UpLoginManager
from qqqr.utils.net import ClientAdapter

with ClientAdapter() as client:
    mgr = UpLoginManager(
        client,
        config=UpLoginConfig.model_validate(
            dict(uin=env.uin, pwd=env.password, fake_ip="8.8.8.8")
        ),
    )
    api = QzoneH5Api(client, mgr)

获取 feed 流

feed_flow = await api.index()
feed_flow = await api.profile(uin=123456789)

获取(自己的)feed 流是大多数操作的初步步骤,因为它从 Qzone 服务器获取 qzonetoken,该 token 在大多数操作中都会用到。

获取 feed 流的下一页

由于 feed 流是分页的,您可以获取 feed 流的下一页:

attach_info = None
while True:
    resp = await api.get_active_feeds(attach_info=attach_info)
    attach_info = resp.attach_info
    if not resp.has_more:
        break
attach_info = None
while True:
    resp = await api.get_feeds(uin=123456789, attach_info=attach_info)
    attach_info = resp.attach_info
    if not resp.has_more:
        break

参见

aioqzone-feed 提供了获取 feed 流的高级接口。

通过 uin 获取头像

这是一个无需登录的 API,不需要登录状态即可获取头像。

size = 100  # avatar size, can be 100, 640
resp = await api.avatar(123456789, size)
with open("out/avatar.png", "wb") as f:
    f.write(resp.avatar)

上传照片

上传照片分为两步。第一步调用 QzoneH5API.upload_pic(),每张图片调用一次,返回文件长度和 md5。第二步调用 :meth:`QzoneH5API.preupload_photos,一次性传入多张图片,返回包含图片 URL、图片 ID 等信息的 PicInfo 列表。

import asyncio

images = ["image_a.jpg", "image_b.jpg", "image_c.jpg"]
hashes = await asyncio.gather(
    *map(api.upload_pic, images)
)
pic_infos = await api.preupload_photos(hashes)

提示

您可以通过设置 QzoneH5API.upload_pic()quality 参数来指定上传图片的质量。

说说操作

发表说说

from aioqzone.model import UgcRight

MOOD_TEXT = "Hello, world!"
picinfo = [...]  # list of PicInfo, can be empty
feed = await api.publish_mood(
    MOOD_TEXT, photos=picinfo, sync_weibo=False, ugc_right=UgcRight.self
)

提示

您可以通过设置 QzoneH5API.publish_mood()ugc_right 参数来指定说说可见性。

删除说说

# get appid from fetch feed. common appid of mood without sharing is 311.
delete_response = await api.delete_ugc(feed.fid, appid)

获取说说详情

# fetching feed
feed_flow = await api.get_active_feeds()
feed_dict = {i.fid: i for i in feed_flow.vFeeds}
fetched_feed = feed_dict[feed.fid]

detail = await api.shuoshuo(
    fetched_feed.fid, fetched_feed.userinfo.uin, fetched_feed.common.appid
)

点赞/取消点赞说说

from aioqzone.model import LikeData

# get appid, curkey and unikey from fetch feed
# common appid of mood without sharing is 311.

# for feeds without forward, curkey and unikey are the same.
# you can construct them by host uin and fid:
# unikey = LikeData.pseudo_unikey(appid, hostuin, feed.fid)

await api.internal_dolike_app(appid, unikey, curkey=unikey, like=True)  # like
await api.internal_dolike_app(appid, unikey, curkey=unikey, like=False) # unlike

说说评论

添加评论

COMMENT_TEXT = "Nice mood!"
comment = await api.add_comment(
    hostuin, feed.fid, appid, COMMENT_TEXT, busi_param=fetched_feed.operation.busi_param
)

小技巧

busi_param 可选,但推荐提供。

COMMENT_TEXT = "Nice mood!"
picinfo = [...]  # list of PicInfo
comment_pic = await api.add_comment(
    hostuin, feed.fid, appid, COMMENT_TEXT, [i.url for i in picinfo]
)

注意

图片评论使用旧版 HTML Qzone API,返回 HTML 响应。目前无法从响应中解析 commentId

删除评论

await api.delete_comment(ownuin, fetched_feed.topicId, comment.commentid)

检查 feed 更新

推测

每 5 分钟调用此 API 可能使登录 cookie 保持一天(或数天)有效,否则登录状态将在几小时内过期。

await api.mfeeds_get_count()