随机壁纸是一个很小的生活服务类接口,作用是返回指定分类和分辨率下的随机壁纸图片 URL。它的请求路径、参数和响应结构都很简单,适合作为 API 调试技巧的入门样例。这篇文章不讨论复杂的架构,只解决一个问题:如何用一条可运行的请求,拿到一张可用的图片链接。
接口概览与适用场景
该接口对接 360 公开壁纸库,上游提供了 16 个分类和 7 种分辨率。接口内部按分类和分辨率对上游响应做缓存,本地再执行随机 shuffle,因此每次请求返回的图片集合不同,但上游请求量并不会随调用次数线性增长。
典型的应用场景包括:
- 登录页背景:每次刷新页面展示不同的风景或动漫壁纸。
- 桌面壁纸小工具:定时请求接口,更换本机桌面。
- 文章封面图:按文章主题选择分类,自动配一张图。
- 小程序首页轮播:用 count 参数一次取多张,交给前端轮播组件。
如果你只是做功能验证,最快的方式就是直接用 curl 请求一次,看返回结构是否满足预期。
请求地址与能力边界
基础信息
- 接口名称:随机壁纸
- slug:wallpaper
- 请求方法:GET
- 请求地址:https://v1.apizero.cn/api/wallpaper
- 分类:生活服务
- QPS:20 / s
- 文档页:https://apizero.cn/aidocs/wallpaper
这里需要明确一个边界:QPS 20 / s 指的是单个 API Key 的调用频率上限,不是接口的并发容量。在实际开发中,即使你的业务量很小,也应该在前端做节流或缓存,不要每次渲染都直接打接口。
Query 参数说明
| 参数名 | 必填 | 类型 | 说明 | 默认值 | 可选值 |
|---|---|---|---|---|---|
| category | 否 | string | 壁纸分类中文名 | 风景 | 16 个分类,见下表 |
| resolution | 否 | string | 目标分辨率 | 1920x1080 | 7 种分辨率,见下表 |
| count | 否 | number | 返回图片数量 | 1 | 1-20 |
16 个分类:美女、风景、游戏、影视、时尚、明星、汽车、萌宠、清新、体育、萌娃、军事、动漫、日历、爱情、格言。
7 种分辨率:
| 分辨率 | 说明 |
|---|---|
| 1920x1080 | 原图 |
| 1600x900 | 宽屏 |
| 1440x900 | 宽屏 |
| 1366x768 | 笔记本常见尺寸 |
| 1280x800 | 宽屏 |
| 1280x1024 | 方屏 |
| 1024x768 | 普屏 |
一个容易忽略的点是 URL 中的分辨率参数用的是字母x,不是星号*,也不是全角乘号。例如1920x1080是正确的,1920*1080会被当成非法参数。
鉴权方式
请求需要携带 API Key,通过 HTTP 头X-API-Key传递。在命令行中可以通过环境变量注入:
export APIZERO_API_KEY="your-key-here"然后在 curl 请求中使用$APIZERO_API_KEY引用。注意不要直接把 Key 写到代码仓库里,尤其是前后端共享的仓库。
curl 最小可运行示例
以下示例按照 API 文档提供的请求方式编写,返回风景分类、1920x1080 分辨率的两张随机壁纸:
curl -sS \ -X GET \ -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/wallpaper?category=风景&resolution=1920x1080&count=2"如果你还没有配置环境变量,可以直接把$APIZERO_API_KEY替换为实际 Key:
curl -sS \ -X GET \ -H "X-API-Key: 你的APIKey" \ "https://v1.apizero.cn/api/wallpaper?category=风景&resolution=1920x1080&count=2"-sS的含义是静默模式但不隐藏错误。去掉-s会显示请求进度信息,不适合脚本化调用;去掉-S则可能在连接失败时没有任何报错输出,不利于排查。
执行成功后,你会得到一个 JSON 数组,数组内只有一个元素,元素中的example字段就是完整的响应体。
使用 jq 快速验证返回结构
如果本机安装了 jq,可以配合 curl 直接提取图片 URL:
curl -sS \ -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/wallpaper?category=风景&resolution=1920x1080&count=2" \ | jq -r '.[0].example.data.images[].url'这条命令的输出是两张图片的完整 URL 列表,可以直接拼接到 curl 之后下载图片:
curl -sS -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/wallpaper?category=风景&resolution=1920x1080&count=1" \ | jq -r '.[0].example.data.images[0].url' \ | xargs curl -sS -o wallpaper.jpg注意xargs curl只适用于 URL 中不包含特殊空格的场景;如果 URL 中包含特殊字符,建议用while read逐行处理。
JavaScript 接入示例
以浏览器环境为例,使用 fetch 发起请求:
const API_KEY = 'your-api-key'; const url = new URL('https://v1.apizero.cn/api/wallpaper'); url.searchParams.set('category', '风景'); url.searchParams.set('resolution', '1920x1080'); url.searchParams.set('count', '1'); const response = await fetch(url, { headers: { 'X-API-Key': API_KEY } }); const payload = await response.json(); const wrapper = payload[0]; if (wrapper.example.code !== 0) { throw new Error(wrapper.example.msg); } const image = wrapper.example.data.images[0]; console.log(image.url);在 Node.js 18+ 中,这段代码可以直接以.mjs文件运行。注意fetch的默认行为不会自动解码中文 URL 参数,URLSearchParams会做正确编码,不要手动拼接 query string。
Python 接入示例
使用urllib.request标准库,不依赖第三方包:
import json import urllib.parse import urllib.request API_KEY = "your-api-key" params = urllib.parse.urlencode({ "category": "风景", "resolution": "1920x1080", "count": "2", }) url = f"https://v1.apizero.cn/api/wallpaper?{params}" req = urllib.request.Request(url, headers={ "X-API-Key": API_KEY, }) with urllib.request.urlopen(req, timeout=10) as resp: payload = json.loads(resp.read().decode("utf-8")) wrapper = payload[0] if wrapper["example"]["code"] != 0: raise RuntimeError(wrapper["example"]["msg"]) for img in wrapper["example"]["data"]["images"]: print(img["url"])这里把超时时间设置为 10 秒。壁纸图片 URL 指向 360 图床,下载图片时建议单独设置更长的超时时间,不要把「拿接口数据」和「下载图片」放在同一个超时控制里。
返回字段解读
响应是一个 JSON 数组,数组内每个元素描述一个响应状态。实际业务数据在example字段中。
以count=2的请求为例,核心结构如下:
{ "code": 0, "data": { "category": "风景", "category_id": 9, "count": 2, "images": [ { "id": 2054209, "resolution": "1920x1080", "tag_text": "海洋天堂 日出东方 松树 海岛", "tags": ["海洋天堂", "日出东方", "松树", "海岛"], "url": "https://p2.qhimg.com/bdr/__85/t019ca75cd449be50c1.jpg" } ], "requested": 2, "resolution": "1920x1080" }, "msg": "成功", "request_id": "abc123def456" }字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| code | number | 状态码,0 表示成功 |
| msg | string | 描述信息 |
| request_id | string | 单次请求的标识,用于排查问题 |
| data.category | string | 实际返回的分类名 |
| data.category_id | number | 分类内部 ID |
| data.count | number | 实际返回的图片数量 |
| data.requested | number | 请求时传入的 count 值 |
| data.resolution | string | 实际返回的分辨率 |
| data.images | array | 图片列表 |
| images[].id | number | 图片 ID |
| images[].resolution | string | 图片分辨率 |
| images[].tag_text | string | 图片标签的文本拼接形式 |
| images[].tags | array | 图片标签数组,便于程序化处理 |
| images[].url | string | 图片完整下载地址 |
其中requested和count的含义不同:requested是你要求返回的数据量,count是实际返回的数据量。在正常状态下两者相等;如果上游图片不足,count会小于requested,但接口仍然返回code=0。这也是一个容易误判的点。
关于返回内容的两个工程细节:
tags数组来自上游内部标记的拆分处理。例如tag_text是海洋天堂 日出东方 松树 海岛,tags就是["海洋天堂", "日出东方", "松树", "海岛"]。如果你的业务需要对图片做标签筛选,直接使用tags数组即可,不需要再按空格切分。- 接口内部已把上游的
http://图片地址强制改写为https://。这避免了在 HTTPS 页面中因加载 HTTP 图片而产生混合内容警告。你拿到的url字段可以直接用于<img>标签。
图片 URL 的使用方式
拿到url后,前端可以直接渲染:
<img src="https://p2.qhimg.com/bdr/__85/t019ca75cd449be50c1.jpg" alt="随机壁纸" />后端可以将 URL 持久化到数据库,也可以直接做图片代理下载:
import urllib.request img_url = "https://p2.qhimg.com/bdr/__85/t019ca75cd449be50c1.jpg" urllib.request.urlretrieve(img_url, "wallpaper.jpg")需要注意的是,图片 URL 的域名是p2.qhimg.com,不是 API 域名。如果你的服务器需要配置白名单,需要把图片域名一并加入。
常见错误与排查
1. HTTP 401 Unauthorized
原因通常是X-API-Key没有正确传递。检查环境变量是否已导出:
echo $APIZERO_API_KEY如果输出为空,说明没有设置环境变量,或者设置到了不同的 shell 进程。
2. HTTP 400 Bad Request
原因通常是 category 或 resolution 参数值不在可选范围内。例如把1920x1080写成1920*1080,或者把分类写成英文fengjing,都会导致参数校验失败。
3. 返回 code 非 0
响应外层的 HTTP 状态可能是 200,但code字段不为 0。此时业务逻辑不应该继续处理图片列表,而是抛出异常。建议把code !== 0视为业务层错误。
4. count 返回数量小于请求值
如前面所述,requested和count不一致时,应使用count作为实际遍历的上限,避免访问不存在的images[i]。
5. 连接超时或 SSL 证书错误
在容器或服务器环境中,检查系统时间和 CA 证书是否正常。开发者可以在代码中显式设置超时时间,例如 Python 的urlopen(..., timeout=10),避免进程长时间阻塞。
工程化注意事项
1. 不要在每次请求时都动态拼接中文参数
建议将分类和分辨率定义为常量。尤其在前端代码中,硬编码中文关键词容易导致 URL 编码问题。
2. 对图片 URL 做缓存而不是只缓存接口响应
接口本身已做了 1 小时的上游缓存,但你的应用层仍需考虑图片 URL 的重复利用。如果一个用户刷新页面 10 次,每次都拿到相同的 URL 集合,直接展示缓存即可,不需要重复请求接口。
3. 控制请求频率
接口 QPS 上限为 20 / s,这不算高。在多人共用同一 API Key 的场景下,建议在网关层做限流,或者把图片 URL 聚合后通过自己的接口下发。
4. 考虑图片域名隔离
前端页面加载图片时,浏览器对p2.qhimg.com的并发连接数可能受限。如果一次展示多张壁纸,建议设置loading="lazy"。
5. 不要把 API Key 暴露给前端
浏览器环境下,X-API-Key可以被用户看到。最佳做法是后端请求该接口,前端再从自己的服务端获取图片数据。
6. 增加维度校验
检查images[].resolution是否真的等于请求参数。虽然接口文档承诺会按参数返回对应分辨率,但作为上游对接方,保留一层校验能降低图片尺寸不符的风险。
小结
随机壁纸接口的最小可运行流程可以概括为三步:
- 构造 GET 请求地址,带上
category、resolution、count三个可选参数。 - 在 HTTP 头中传入
X-API-Key。 - 解析返回数组中的
example.data.images,取出url字段。
整个调试过程不需要复杂的客户端或依赖库,curl + jq 即可完成链路验证。对于需要嵌入业务系统的开发者,可以直接参考 JavaScript 或 Python 的接入片段,并在工程化层面重视缓存、超时、参数校验三项基础问题。
参考文档
- 接口文档:https://apizero.cn/aidocs/wallpaper
- 原始文档:https://apizero.cn/aidocs/wallpaper/raw.md