示例¶
本页提供 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()