ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

域名交易市场数据筛选实战:Query 参数边界与分页遍历避坑

域名交易市场数据筛选实战:Query 参数边界与分页遍历避坑

适用场景与接口定位

域名交易市场的公开数据对以下几类开发者有直接价值:

  • 站长/域名投资人:按用量说明、长度、后缀筛选目标域名,快速缩小选品范围。
  • 行业研究:拉取一段时间内的交易记录,分析热门后缀分布、用量说明区间走势。
  • 估值参考:结合同后缀、同长度的成交用量说明,辅助判断某个域名的合理估值区间。

该接口定位为只读的数据查询接口,返回的是 EDNS 域名交易市场的公开挂牌/成交信息。它不承担下单、竞价、支付等交易链路,接入前应明确这一点:接口只负责数据,不负责业务闭环

接口能力边界

在写代码之前,先确认几个事实:

项目说明
请求方法GET
请求地址https://v1.apizero.cn/api/domain-trade
分类金融数据
QPS 上限5 / s
鉴权方式HeaderX-API-Key
数据返回JSON 数组格式的响应体

QPS 5/s 意味着单机并发拉取需要做限速。如果你的任务需要遍历全部数据页,建议每次请求间隔 200ms 以上,避免触发限流。

鉴权方式

接口通过请求头X-API-Key传递 API Key,例如:

curl -sS \ -X GET \ -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/domain-trade?page=1&pagesize=10"

$APIZERO_API_KEY是环境变量占位,实际调用时请替换为你自己的 Key。不要把 Key 硬编码到前端页面或公开仓库中。

Query 参数逐个拆解

接口共支持 6 个查询参数,全部非必填。参数之间是**叠加过滤(AND)**关系,即同时传入多个参数时,返回的数据要同时满足所有条件。

page

  • 类型:number
  • 默认值:1
  • 语义:页码
  • 注意点:页码从 1 开始。如果传 0 或负数,接口行为未在文档中明确,稳妥做法是在业务层拦截非法值。

pagesize

  • 类型:number
  • 默认值:50
  • 上限:100
  • 语义:每页返回的域名记录数

这里有一个容易忽略的细节:pagesize 的合法范围是 1 ≤ pagesize ≤ 100。传 0 或大于 100 的值,接口可能拒绝或按上限截断。为了行为可控,建议在构造请求前先做一次入参归一化:

pagesize = max(1, min(pagesize, 100))

max_price

  • 类型:number
  • 语义:最高用量说明(元)
  • 过滤方向:只返回用量说明 ≤max_price的记录

用量说明字段在响应中是字符串类型(如"5000"),但入参是数字类型。构造筛选条件时,不要把max_price写成带单位的字符串,也不要传小数位数过多的浮点数。建议以整数元为单位。

max_length

  • 类型:number
  • 语义:域名最大长度

这个参数需要特别留意:长度计算的基准是什么?是否包含后缀?例如max_length=8时,abcdefg.com是算 7 个字符还是 11 个字符?不同数据源的口径可能不同,建议在接入前通过文档或少量抽样请求确认口径。若文档未明确,默认按域名主标签(不含点号和后缀)长度理解,但生产环境应以上游实际行为为准。

suffix

  • 类型:string
  • 语义:后缀过滤

传值时带上点号,例如.com.net。如果你用com这种无点号的写法,可能匹配不到预期结果。建议在请求前做一次格式化:

suffix = suffix.strip().lower() if not suffix.startswith("."): suffix = "." + suffix

sale_type

  • 类型:string
  • 语义:交易类型

常见的交易类型包括一口价、竞价、拍卖等,具体枚举值以文档为准。这是一个精确匹配参数,不是模糊搜索,传值时需要与数据源使用的文案完全一致。

请求示例

基础 curl

拉取第一页 20 条数据:

curl -sS \ -X GET \ -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/domain-trade?page=1&pagesize=20"

组合筛选 curl

筛选用量说明不超过 200、长度不超过 6 位的.com域名:

curl -sS \ -X GET \ -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/domain-trade?page=1&pagesize=50&max_price=2000&max_length=6&suffix=.com"

Python 请求模板

import requests API_URL = "https://v1.apizero.cn/api/domain-trade" def fetch_domain_trade(api_key: str, params_pack: dict) -> dict: headers = {"X-API-Key": api_key} resp = requests.get(API_URL, headers=headers, params=params_pack, timeout=10) resp.raise_for_status() return resp.json() if __name__ == "__main__": params = { "page": 1, "pagesize": 50, "max_price": 5000, "max_length": 8, "suffix": ".com", "sale_type": "一口价", } result = fetch_domain_trade("YOUR_API_KEY", params) print(result)

timeout=10是超时兜底,避免网络异常时请求线程被长时间挂起。

响应结构解读

接口的响应示例结构如下:

{ "code": 0, "msg": "成功", "data": { "count": 50, "current_page": 1, "total_pages": 1234, "list": [ { "name": "abc.com", "price": "5000", "sale_type": "一口价" } ] } }

顶层字段

字段类型含义
codenumber业务状态码,0 表示成功
msgstring状态描述
dataobject业务数据体

data 对象

字段类型说明
countnumber当前页实际返回的记录条数
current_pagenumber当前页码
total_pagesnumber总页数
listarray域名记录数组

list 内的域名对象

字段类型说明
namestring域名,如abc.com
pricestring用量说明(元),字符串类型
sale_typestring交易类型,如一口价

注意price是字符串而不是数字。如果你需要对用量说明做排序或区间统计,先做类型转换:

price_num = float(item["price"])

分页遍历的坑

分页遍历最容易踩的坑是count判断是否还有下一页。实际上count表示当前页的记录数,当最后一页数据不满一页时,count < pagesize可以辅助判断结束,但更可靠的终止条件是current_page >= total_pages

推荐的分页遍历逻辑:

page = 1 while True: params = {"page": page, "pagesize": 50} payload = fetch_domain_trade(api_key, params) data = payload["data"] # 业务处理 for item in data["list"]: process_domain(item) if page >= data["total_pages"]: break page += 1 time.sleep(0.3) # QPS 限速兜底

这个写法的好处是:不依赖count的边界行为,而是以服务端给出的total_pages作为遍历终点,语义清晰且不容易死循环。

另一个建议:如果只需要最新一页的数据,不要为了“保险”而强制翻完所有页。这既浪费配额,也容易触发限流。

常见错误排查

401 鉴权失败

  • 现象:接口返回 401 或提示非法 Key
  • 排查:
    1. 确认X-API-Key的拼写是否正确
    2. 确认环境变量$APIZERO_API_KEY是否已导出
    3. 确认 Key 没有被误放进 Query 参数中

业务 code 非 0

  • 现象:HTTP 200,但响应中的code不等于 0
  • 排查:
    1. 逐项核对每个 Query 参数的类型是否符合文档
    2. pagesize是否超过 100
    3. max_price是否为负数
    4. suffix是否带了点号

数据与预期不符

  • 现象:请求成功,但过滤结果看起来不对
  • 排查:
    1. max_length的长度口径是否包含后缀
    2. sale_type的枚举文案是否与文档完全一致
    3. 是否同时传了多个参数,且它们之间有业务上的矛盾(如既要求低价又要求超短域名)

限流

  • 现象:请求偶尔超时或返回限流提示
  • 排查:检查本地是否有并发循环请求,QPS 是否超过 5/s。建议在代码中加入节流控制或请求间隔。

工程化注意事项

参数校验前置

不要把上游接口当成校验器。在业务层提前拦截非法参数:

def build_domain_trade_params( page: int = 1, pagesize: int = 50, max_price: int | None = None, max_length: int | None = None, suffix: str | None = None, sale_type: str | None = None, ) -> dict: if page < 1: raise ValueError("page must be >= 1") if not (1 <= pagesize <= 100): pagesize = 50 params = {"page": page, "pagesize": pagesize} if max_price is not None: if max_price < 0: raise ValueError("max_price must be >= 0") params["max_price"] = int(max_price) if max_length is not None: if max_length < 1: raise ValueError("max_length must be >= 1") params["max_length"] = int(max_length) if suffix: suffix = suffix.strip().lower() if not suffix.startswith("."): suffix = "." + suffix params["suffix"] = suffix if sale_type: params["sale_type"] = sale_type return params

把响应封装成领域模型

响应中的price是字符串,直接用于计算容易出问题。建议在数据入口统一转换:

@dataclass class DomainTrade: name: str price: float sale_type: str def parse_domain_item(raw: dict) -> DomainTrade: return DomainTrade( name=raw["name"], price=float(raw["price"]), sale_type=raw["sale_type"], )

用环境变量管理 Key

不要把 Key 写在代码仓库里。建议使用.env文件或 CI/CD 的 Secret 管理:

export APIZERO_API_KEY=your_key_here

日志与监控

建议记录以下信息,便于线上排查:

  • 请求的完整 URL(Key 打码)
  • 响应状态码与业务 code
  • 请求耗时
  • 当前页与总页数

小结

域名交易市场接口整体不复杂,核心价值在于Query 参数的精确组合分页遍历的正确终止。接入时把参数校验前置、遍历逻辑按total_pages收敛、用量说明字段统一转浮点,可以避开绝大多数使用上的坑。长度筛选的口径和交易类型枚举值建议以最新文档为准,必要时通过小批量请求验证行为。

参考文档

  • 接口文档页:https://apizero.cn/aidocs/domain-trade
  • 原始文档:https://apizero.cn/aidocs/domain-trade/raw.md
返回列表