×

《别混淆两套接口:闲管家居家发布 vs 第三方数据采集的边界与合规红线》(附Python源码)

万邦科技Lex 万邦科技Lex 发表于2026-09-23 09:17:59 浏览35 评论0

抢沙发发表评论

《别混淆两套接口:闲管家居家发布 vs 第三方数据采集的边界与合规红线》(附Python源码)

先拍结论:
闲管家/官方 alibaba.idle.isv.* 是“管自己店铺的写通道”;第三方数据采集是“看别人商品的读通道”。
把采集到的同行商品直接无脑铺货、把爬虫当发布接口、把买家地址存到公网——这三条任踩一条,都不是“BUG”,是合规事故

一、两套通道的本质区别(别再混了)

维度
A 路:闲管家 / 官方 ISV 通道
B 路:第三方数据采集
身份
自家卖家 OAuth 授权 + AppKey
第三方聚合 Key / 搜索接口
典型接口
alibaba.idle.isv.item.publish / .ship / refund.query
item_search / item_get / shop_items
数据范围
仅授权卖家自己的商品/订单
平台公开/半公开商品、竞品、货源
能写吗
能发商品、改价、发货、关单
不能写,发不了闲鱼商品
部署位置
聚石塔内(写操作强制入塔)
公网/采集服务即可
合规基础
平台合同 + scope + 可审计
个保法 / 反不正当竞争 / 平台反爬规则
越界后果
超 scope 被拦截、应用降权
账号风控、封号、民事侵权、刑责风险
一句话:
  • A 路:光明正大按规矩干(但只能干自己的)

  • B 路:可以看市场,但不能假装自己是闲鱼后台


二、最容易混用的 4 个错误

  1. 拿第三方搜索接口去发商品
    → 第三方接口没有卖家 session,发不了;硬发就是伪造/抓包。

  2. 把同行商品图+描述直接搬进自家店铺
    → 侵权/盗图/虚假描述,闲鱼直接下架+降权。

  3. 采集买家昵称/聊天/手机号做“用户画像”
    → 个保法红线,R2 数据禁止出塔、禁止二次利用。

  4. 用 RPA/闲管家自动化“擦亮+跟价+批量采同行”当主链路
    → RPA 本质是替人点网页,不是官方 API;规模一大必被风控。


三、合规红线(系统里必须写成硬拦截)

✅ 允许:
- 用官方API发“自己供应链”的商品
- 用采集接口做“选品/比价/货源发现”
- 采集数据进“选品池”,人工/规则过滤后再上架

❌ 禁止:
- 绕开TOP直接请求闲鱼H5/APP接口
- 批量抓同行定价做“自动跟价”
- 存买家手机号/地址/聊天记录到公网ERP
- 把采集商品原样铺货
- 用RPA模拟登录当生产主链路

四、双通道边界守卫(生产向代码)

# commerce_mesh/compliance/channel_guard.py
from enum import Enum
from dataclasses import dataclass
from typing import Callable


class Channel(str, Enum):
    OFFICIAL_ISV = "official_isv"      # alibaba.idle.isv.*
    DATA_COLLECT = "data_collect"      # 第三方只读采集
    RPA_HACK = "rpa_hack"              # 模拟登录/抓包 —— 永远不允许写


class Action(str, Enum):
    PUBLISH_ITEM = "publish_item"
    SHIP_ORDER = "ship_order"
    REFUND_HANDLE = "refund_handle"
    SEARCH_ITEMS = "search_items"
    SCRAPE_SHOP = "scrape_shop"
    STORE_BUYER_PII = "store_buyer_pii"


# 通道 × 动作 白名单
CHANNEL_ALLOWLIST = {
    Channel.OFFICIAL_ISV: {
        Action.PUBLISH_ITEM, Action.SHIP_ORDER,
        Action.REFUND_HANDLE,
    },
    Channel.DATA_COLLECT: {
        Action.SEARCH_ITEMS,  # 只读
    },
    Channel.RPA_HACK: set(),  # 全部拒绝
}

# 数据采集结果禁止直接进“发布流水线”
COLLECT_TO_PUBLISH_BLOCKED = True


@dataclass
class ChannelContext:
    channel: Channel
    seller_id: str
    action: Action
    payload: dict


class ComplianceGate:
    def __init__(self):
        self.audit_log = []

    def check(self, ctx: ChannelContext) -> dict:
        allowed_actions = CHANNEL_ALLOWLIST.get(ctx.channel, set())

        # 1. 通道×动作白名单
        if ctx.action not in allowed_actions:
            self._audit(ctx, "DENY_CHANNEL_ACTION")
            return {
                "allowed": False,
                "reason": f"{ctx.channel} 不允许执行 {ctx.action}",
            }

        # 2. 采集通道禁止写操作(双保险)
        if ctx.channel == Channel.DATA_COLLECT and ctx.action in (
            Action.PUBLISH_ITEM, Action.SHIP_ORDER, Action.REFUND_HANDLE
        ):
            self._audit(ctx, "DENY_COLLECT_WRITE")
            return {"allowed": False, "reason": "采集通道只能读,不能写"}

        # 3. PII 红线
        if ctx.action == Action.STORE_BUYER_PII:
            self._audit(ctx, "DENY_PII")
            return {"allowed": False, "reason": "禁止存储买家PII到公网ERP"}

        # 4. 采集数据直接铺货拦截
        if (ctx.channel == Channel.DATA_COLLECT
                and ctx.payload.get("auto_publish_from_scrape")):
            self._audit(ctx, "DENY_SCRAPE_TO_PUBLISH")
            return {"allowed": False, "reason": "采集商品必须经人工/规则过滤,禁止无脑铺货"}

        self._audit(ctx, "ALLOW")
        return {"allowed": True}

    def _audit(self, ctx: ChannelContext, verdict: str):
        self.audit_log.append({
            "seller_id": ctx.seller_id,
            "channel": ctx.channel.value,
            "action": ctx.action.value,
            "verdict": verdict,
        })

# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
# -------- 业务侧用法 --------
def publish_own_item(gate: ComplianceGate, seller_id: str, item: dict):
    ctx = ChannelContext(
        channel=Channel.OFFICIAL_ISV,
        seller_id=seller_id,
        action=Action.PUBLISH_ITEM,
        payload=item,
    )
    res = gate.check(ctx)
    if not res["allowed"]:
        raise PermissionError(res["reason"])
    # 真正调 alibaba.idle.isv.item.publish(聚石塔内)
    return {"ok": True, "via": "official_isv"}


def ingest_scraped_item(gate: ComplianceGate, scraped: dict):
    ctx = ChannelContext(
        channel=Channel.DATA_COLLECT,
        seller_id="market-watch",
        action=Action.SEARCH_ITEMS,
        payload={"auto_publish_from_scrape": scraped.get("auto_publish", False)},
    )
    res = gate.check(ctx)
    if not res["allowed"]:
        # 进“选品池”,不进“上架池”
        return {"ok": False, "routed_to": "candidate_pool", "reason": res["reason"]}
    return {"ok": True, "routed_to": "candidate_pool"}

五、数据流向应该是这样

[第三方采集] ──▶ 选品池 / 比价表 / 竞品监控
                    │
                    │ 人工审核 / 成色重拍 / 去水印 / 重写字案
                    ▼
[自有供应链商品] ──▶ 官方ISV通道 ──▶ 闲鱼发布
                    │
                    ▼
              聚石塔内订单/退款/发货
                    │
                    ▼
            脱敏事件回传公网ERP
关键隔离:
  • 采集数据 ≠ 上架数据

  • 同行标题 ≠ 自家标题

  • 同行图 ≠ 自家图

  • 买家信息 ≠ ERP 宽表字段


六、和前几篇的收口

  • 《聚石塔入塔》:写操作只能在 A 路 + 塔内;B 路永远没有写权限

  • 《order.ship 实录》:ship 用卖家 session,采集接口根本拿不到

  • 《六大坑》:编码/PII/消息丢失之外,“通道误用”是第 7 个坑

  • 《中台调度》XianyuAdapter.publish() 只接自有商品;ScrapeAdapter 只接选品池


七、一句话收口

官方 ISV 通道 = 自己开店的正门;第三方采集 = 站在街对面看行情。
正门不能用来偷看别人账本,街对面不能冲进去搬货。
二手 ERP 的成熟标志,不是“能采多少”,而是“采集进选品池、自有商品才进发布池”
要不要下一篇写:
《选品池 → 自有商品池的清洗流水线:去水印 / 成色重标 / 侵权词过滤 / 自动重写字案》
把“采集数据变成可发布商品”的那道防火墙写成完整模块?


群贤毕至

访客