返回教程列表
教程2026年10月11日5 分钟阅读

小红书蒲公英 API 教程:达人筛选、合作报价与粉丝画像

通过 Just One API 按粉丝数量筛选小红书蒲公英达人,获取达人资料、图文与视频合作报价及粉丝画像。包含保留空值、分页去重和保存候选名单的 Python 示例。

从粉丝范围筛选到达人候选名单

准备小红书达人合作时,通常需要先找出符合规模要求的账号,再检查报价和受众是否合适。Just One API 的小红书蒲公英接口可以把这几个步骤串起来:搜索达人,获取资料,再获取粉丝画像。

本教程以粉丝数 1 万到 10 万的达人为例,最多读取两页搜索结果,为其中三位达人保存资料、报价和画像。这个范围用于演示筛选流程,你可以按项目要求调整。输出是待评估的候选名单,合作决策仍需结合内容质量、报价可见性和业务需求。

如果目标是小红书笔记正文或评论,请先看小红书与蒲公英的数据范围区别。这篇教程聚焦蒲公英的达人营销数据。

注册、获取 Token 并在线测试

注册 Just One API 后获取 API Token,即可通过在线接口文档免费测试。一个 Token 可用于多个平台接口,后续按实际调用量付费;各接口的可用权限和免费测试次数以账户显示为准。

先打开达人搜索 V1,填写 Token、粉丝上下限和页码,检查返回体的业务 code 是否为 0。HTTP 请求成功与业务成功要分别判断。

教程使用三个 GET 接口,均通过查询参数 token 鉴权。脚本从环境变量读取 Token,不在源代码中保存真实值,也不输出带 Token 的完整请求地址。

第一步:筛选达人并保留 userId

搜索接口的路径为 /api/xiaohongshu-pgy/api/solar/cooperator/blogger/v2/v1。本例设置以下参数:

  • fansNumberLower=10000、fansNumberUpper=100000:筛选粉丝数量范围。
  • sort=FANS:按粉丝数降序;需要平台智能排序时使用 DEFAULT。
  • page=1:从第一页开始,下一页递增页码。

当前公开响应样例把达人列表放在 data.kols,每条记录的 userId 用于后续查询。脚本按这个 ID 去重,再选取少量达人查询详情。

搜索结果中的 total 可以辅助了解平台返回的结果规模,但不应直接当作全平台达人总数。示例设置最多两页,并在空列表或整页没有新增 ID 时停止,防止重复采集。修改筛选条件后,应从第一页重新开始。

第二步:读取达人资料和合作报价

把搜索得到的 userId 传给达人资料 V1。当前公开样例中的资料字段包括 data.name、data.fansCount、data.picturePrice、data.videoPrice 和 data.showPrice。

其中图文与视频报价可能为空。报价为 null 表示本次没有拿到对应值,不能填成 0,也不能据此认定达人免费合作。showPrice 与原始报价一起保留,便于之后判断显示状态。进入预算比较前,还要确认当前字段的单位、合作形式和适用条件。

脚本会保存完整资料响应,同时生成便于查看的 shortlist.json。搜索页与资料页可能在不同时间返回数据,出现差异时保留两个原始响应,并记录采集时间,避免静默覆盖。

第三步:获取粉丝画像

使用同一个 userId 调用粉丝分布 V1。当前公开样例包含这些字段:

  • data.ages:年龄分组,其中包含 group 和 percent。
  • data.gender:性别分布。
  • data.provinces、data.cities:地域分布。
  • data.interests、data.devices:兴趣与设备相关分布。
  • data.dateKey:画像数据对应的日期标记。

这些分布适合辅助判断候选达人是否接近目标受众。做报表前先确认各字段的单位与分母,避免把比例值统一乘以 100,或把某个分组缺失理解为零。示例保留整个画像对象,并把 dateKey 写进候选名单,便于核对数据时点。

Python 示例:保存候选名单、资料和画像

安装依赖并设置环境变量。把 your_token 替换成自己的 Token;下面的命令适用于 macOS 或 Linux 终端。

bash
python3 -m pip install requests
export JUSTONEAPI_TOKEN='your_token'

保存下方代码为 pugongying_sample.py,运行 python3 pugongying_sample.py。最多请求两页搜索结果,再查询三位达人的资料与画像,总计不超过 8 次 API 请求;提前结束或出错时次数更少。这是示例的采样上限,不是接口配额。

python
import json
import os
from datetime import datetime, timezone
from pathlib import Path

import requests

BASE_URL = "https://api.justoneapi.com"
TOKEN = os.environ.get("JUSTONEAPI_TOKEN", "")


def call_api(path, **params):
    try:
        response = requests.get(
            BASE_URL + path,
            params={"token": TOKEN, **params},
            timeout=120, allow_redirects=False,
        )
    except requests.RequestException:
        raise RuntimeError("API network error or timeout") from None
    if response.status_code != 200:
        raise RuntimeError(f"API HTTP {response.status_code}")
    try:
        result = response.json()
    except ValueError:
        raise RuntimeError("API response is not JSON") from None
    if not isinstance(result, dict) or result.get("code") != 0:
        code = result.get("code") if isinstance(result, dict) else None
        raise RuntimeError(f"API failed: code={code}; check the docs")
    data = result.get("data")
    if not isinstance(data, dict):
        raise RuntimeError("Unexpected data shape; inspect the docs")
    inner = data.get("base_resp")
    if isinstance(inner, dict) and inner.get("status_code") not in (0, "0"):
        raise RuntimeError("Platform response was unsuccessful")
    return result


def save_json(folder, name, value):
    (folder / name).write_text(
        json.dumps(value, ensure_ascii=False, indent=2), encoding="utf-8"
    )


def require_list(data, key):
    value = data.get(key)
    if not isinstance(value, list):
        raise RuntimeError(f"Expected a list at {key}; inspect saved JSON")
    return value


def output_folder(topic):
    if not TOKEN or TOKEN == "your_token":
        raise RuntimeError("Set JUSTONEAPI_TOKEN before running")
    run_id = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S%fZ")
    folder = Path(topic + "-output") / run_id
    folder.mkdir(parents=True, exist_ok=False)
    return folder


MAX_PAGES = 2
MAX_CREATORS = 3
SEARCH = "/api/xiaohongshu-pgy/api/solar/cooperator/blogger/v2/v1"
PROFILE = "/api/xiaohongshu-pgy/api/solar/cooperator/user/blogger/userId/v1"
AUDIENCE = "/api/xiaohongshu-pgy/api/solar/kol/data/userId/fans_profile/v1"


def main():
    folder = output_folder("pugongying")
    ids, seen = [], set()
    for page in range(1, MAX_PAGES + 1):
        result = call_api(
            SEARCH, page=page, sort="FANS",
            fansNumberLower=10000, fansNumberUpper=100000,
        )
        save_json(folder, f"search-{page}.json", result)
        rows = require_list(result["data"], "kols")
        if not rows:
            break
        previous_count = len(ids)
        for row in rows:
            uid = row.get("userId") if isinstance(row, dict) else None
            if uid and str(uid) not in seen:
                seen.add(str(uid))
                ids.append(str(uid))
        if len(ids) == previous_count:
            break

    selected = ids[:MAX_CREATORS]
    save_json(folder, "selected-creators.json", selected)
    summary = []
    for index, uid in enumerate(selected, start=1):
        profile = call_api(PROFILE, userId=uid)
        save_json(folder, f"creator-{index}-profile.json", profile)
        audience = call_api(AUDIENCE, userId=uid)
        save_json(folder, f"creator-{index}-audience.json", audience)
        data = profile["data"]
        summary.append({
            "userId": uid, "name": data.get("name"),
            "fansCount": data.get("fansCount"),
            "picturePrice": data.get("picturePrice"),
            "videoPrice": data.get("videoPrice"),
            "showPrice": data.get("showPrice"),
            "audienceDate": audience["data"].get("dateKey"),
        })
    save_json(folder, "shortlist.json", summary)
    print(f"Saved {len(selected)} creator samples to {folder}")


if __name__ == "__main__":
    try:
        main()
    except RuntimeError as error:
        raise SystemExit(str(error)) from None

如何使用输出结果

每次运行会创建独立的 pugongying-output 时间目录。selected-creators.json 保存选中的 ID,shortlist.json 汇总名称、粉丝数、原始报价及画像日期,各个 creator-*-profile.json 和 creator-*-audience.json 保留完整响应。

先审核候选名单,再按需要扩大详情采集量,有助于控制调用次数。若要转成 CSV,应把未知报价保留为空,并单独标注数据缺失;不要让表格软件把未知值统计成零成本。

常见问题

已经有达人 ID,还要搜索吗?

不需要。确认是对应蒲公英达人的 userId 后,可以直接调用资料和粉丝分布接口。昵称可能重复或发生变化,不适合作为关联主键。

为什么有些报价或画像字段没有值?

字段可用性取决于当次响应。先区分接口失败、完整对象中某字段为空、以及结果列表为空,再决定是否需要重试或人工核对。脚本遇到业务失败会停止,并保留已经保存的成功响应,不会把失败结果包装成有效候选数据。

可以用同一套程序持续更新吗?

可以在这套流程上增加任务调度与增量存储。建议按 userId 和采集时间保留快照,单独记录每次筛选条件,并给分页、并发和重试设置上限。重试方式可参考接口失败后的处理策略。

从达人搜索文档测试一页数据,再按你的筛选条件生成第一份候选名单。

继续使用 Just One API

登录 Dashboard 获取 Token,查看完整 API 文档,或打开 MCP GitHub 项目了解最新配置。