接口概述
一句话说明
address.parse 把一段非结构化的收货地址文本,
解析成「姓名 + 电话 + 地址文字 + 省 / 市 / 区县名称与 adcode」的结构化结果。
前半程由大模型做语义抽取,后半程用平台自有的行政区划库(region_data,每周日同步)
把大模型给出的地名规范化并补齐行政区划代码,避免模型返回的名称与库里不一致导致匹配失败。
| 请求地址 | https://api.xujian.tech/openapi/address/parse |
|---|---|
| 请求方式 | GET(text 放 Query String)或 POST(text 放 JSON body) |
| 鉴权方式 | 请求头 X-API-Key(不做签名与加密) |
| 接口编码 | address.parse |
| 收费类型 | PER_CALL(按次计费,0.0200 元/次) |
| 计费特殊规则 | 解析失败不收费:文本为空 / 超长、大模型不可用、 识别不出地址或省级行政区时,返回失败且不扣费、不写扣费流水 |
| 响应格式 | JSON,Content-Type: application/json;charset=UTF-8 |
| 是否需要授权 | 否(无需授权,API Key 有效且余额充足即可调用) |
| 文本长度上限 | 200 个字符(超出直接返回失败,不计费) |
| 典型用途 | 电商 / 物流收货地址结构化、订单地址清洗、省市区自动归类、地址三级联动回显、邮编填充、报表区域统计 |
快速开始
把 你的APIKey 换成控制台获取的 API Key,解析一段含姓名、电话、地址的文本:
curl -s -G "https://api.xujian.tech/openapi/address/parse" \
--data-urlencode "text=张三,13020260925,重庆市铜梁区白龙大道龙腾盛世" \
-H "X-API-Key: 你的APIKey"
地址含逗号、换行等特殊字符时,改用 POST(JSON body)
curl -s "https://api.xujian.tech/openapi/address/parse" \
-H "X-API-Key: 你的APIKey" \
-H "Content-Type: application/json" \
-d '{"text":"张三,13020260925,重庆市铜梁区白龙大道龙腾盛世"}'
解析结果示例
输入「张三,13020260925,重庆市铜梁区白龙大道龙腾盛世」,接口返回:
name= 张三、phone= 13020260925address= 重庆市铜梁区白龙大道龙腾盛世(直辖市不重复拼接市名)province= 重庆市、provinceCode= 500000city= 重庆市、cityCode= 500000(直辖市市级即省级)district= 铜梁区、districtCode= 500151
请求参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
X-API-Key |
String | 是 | 开发者 API Key,在控制台创建后获取;缺失或无效会返回失败 |
Content-Type |
String | POST 时必填 | POST 时固定为 application/json |
| 参数名 | 类型 | 必填 | 示例 | 说明 |
|---|---|---|---|---|
text |
String | 是 | 张三,13020260925,重庆市铜梁区白龙大道龙腾盛世 | 待解析的原始文本,可包含姓名、电话、地址,顺序不限。 最大 200 个字符;换行、制表符会被自动归一为空格。 GET 放在 Query String,POST 放在 JSON body 的同名字段。 为空时返回「text 不能为空(GET 传 Query 参数,POST 传 JSON {"text":"..."})」,不计费 |
响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
code |
int | 状态码,0 表示成功,非 0 表示失败(常见为 500) |
msg |
String | 结果描述,成功为 success,失败为具体原因 |
data |
Object | 业务数据,失败时为 null |
| 字段 | 类型 | 示例 | 说明 |
|---|---|---|---|
name |
String | 张三 | 收件人姓名;识别不到时返回空字符串(不会返回 null) |
phone |
String | 13020260925 | 联系电话,只保留数字(去掉 +86、空格、横线等);识别不到时返回空字符串 |
address |
String | 重庆市铜梁区白龙大道龙腾盛世 | 地址文字:用库内规范名拼接的「省 + 市 + 区县 + 详细地址」 |
province |
String | 重庆市 | 省级行政区规范名称(库内名称,如「四川省」「内蒙古自治区」) |
provinceCode |
String | 500000 | 省级行政区划代码(6 位 adcode) |
city |
String | 重庆市 | 地级市名称;直辖市返回直辖市名;识别不到时返回空字符串 |
cityCode |
String | 500000 | 地市级行政区划代码(6 位 adcode);识别不到时返回空字符串 |
district |
String | 铜梁区 | 区 / 县名称;识别不到时返回空字符串(此时仍会返回省 / 市) |
districtCode |
String | 500151 | 区县级行政区划代码(6 位 adcode;省直辖县级行政区为 9 位,如 419001000) |
detail |
String | 白龙大道龙腾盛世 | 详细地址(去掉省市区后的道路、门牌、小区、楼栋等原文) |
zipCode |
String | 402500 | 邮政编码(匹配到区县时带回;未匹配到返回空字符串) |
apiCode |
String | address.parse | 接口编码 |
apiName |
String | 地址信息解析 | 接口名称 |
chargeType |
String | PER_CALL | 计费类型:FREE 免费 / PER_CALL 按次 / MONTHLY 按月 / YEARLY 按年(本接口后台配置为 PER_CALL) |
balance |
BigDecimal | 99.9800 | 调用完成后(已扣费)的账户余额(元) |
costMs |
Long | 1820 | 本次调用耗时(毫秒);含大模型调用耗时,通常比纯查询类接口慢 |
响应示例
成功(code = 0)—— 直辖市地址
{
"code": 0,
"msg": "success",
"data": {
"name": "张三",
"phone": "13020260925",
"address": "重庆市铜梁区白龙大道龙腾盛世",
"province": "重庆市",
"provinceCode": "500000",
"city": "重庆市",
"cityCode": "500000",
"district": "铜梁区",
"districtCode": "500151",
"detail": "白龙大道龙腾盛世",
"zipCode": "402500",
"apiCode": "address.parse",
"apiName": "地址信息解析",
"chargeType": "PER_CALL",
"balance": 99.9800,
"costMs": 1820
}
}
直辖市没有「地级市」这一层:city 与 province 同名,
cityCode 取省级代码(如重庆市 500000),区县在该直辖市范围内匹配。
成功(code = 0)—— 普通省市,大模型返回简称也能匹配
{
"code": 0,
"msg": "success",
"data": {
"name": "李四",
"phone": "13800138000",
"address": "四川省成都市郫都区红光镇家园路88号5栋2单元",
"province": "四川省",
"provinceCode": "510000",
"city": "成都市",
"cityCode": "510100",
"district": "郫都区",
"districtCode": "510117",
"detail": "红光镇家园路88号5栋2单元",
"zipCode": "611700",
"apiCode": "address.parse",
"apiName": "地址信息解析",
"chargeType": "PER_CALL",
"balance": 99.9600,
"costMs": 1530
}
}
成功(code = 0)—— 只写到市,区县返回空字符串
{
"code": 0,
"msg": "success",
"data": {
"name": "",
"phone": "",
"address": "浙江省杭州市文一西路969号",
"province": "浙江省",
"provinceCode": "330000",
"city": "杭州市",
"cityCode": "330100",
"district": "",
"districtCode": "",
"detail": "文一西路969号",
"zipCode": "",
"apiCode": "address.parse",
"apiName": "地址信息解析",
"chargeType": "PER_CALL",
"balance": 99.9400,
"costMs": 1410
}
}
失败(识别不出地址 / 省级行政区)—— 不收费
{
"code": 500,
"msg": "未能从文本中识别出有效地址(至少需要能定位到省级行政区),请补充更完整的地址后重试;本次调用不计费",
"data": null
}
错误码与常见失败原因
| code | msg(示例) | 处理建议 |
|---|---|---|
| 0 | success | 调用成功 |
| 500 | 缺少请求头 X-API-Key | 在请求头中补充 X-API-Key |
| 500 | API Key 无效 / API Key 已停用 | 检查 Key 是否正确,或在控制台重新启用 |
| 500 | 客户不存在或已停用 | 联系平台运营确认账号状态(可联系微信xujian_cq) |
| 500 | 接口不存在或已停用 | 确认接口编码 address.parse 当前是否维护中 |
| 500 | 余额不足,请先充值。可联系微信xujian_cq | 按次计费接口在调用前校验余额,余额不足时不扣费,充值后重试(可联系微信xujian_cq) |
| 500 | text 不能为空(GET 传 Query 参数,POST 传 JSON {"text":"..."}) | 补充 text 参数;不计费 |
| 500 | text 长度不能超过 200 个字符 | 缩短文本或本地先做拆分;不计费 |
| 500 | 未能从文本中识别出有效地址(至少需要能定位到省级行政区),请补充更完整的地址后重试;本次调用不计费 | 补充省 / 直辖市信息后重试;不计费 |
| 500 | 地址解析服务暂时不可用(请求大模型超时或网络异常),本次调用不计费 | 稍后重试;不计费 |
多语言代码示例
Java(Hutool)
String text = "张三,13020260925,重庆市铜梁区白龙大道龙腾盛世";
String body = HttpRequest.get("https://api.xujian.tech/openapi/address/parse")
.form("text", text)
.header("X-API-Key", apiKey)
.timeout(30000)
.execute()
.body();
JSONObject json = JSONUtil.parseObj(body);
if (json.getInt("code") == 0) {
JSONObject data = json.getJSONObject("data");
System.out.println(data.getStr("name") + " " + data.getStr("phone"));
System.out.println(data.getStr("province") + data.getStr("city") + data.getStr("district"));
System.out.println(data.getStr("provinceCode") + " / " + data.getStr("cityCode")
+ " / " + data.getStr("districtCode"));
}
Python
import requests
resp = requests.post(
"https://api.xujian.tech/openapi/address/parse",
json={"text": "张三,13020260925,重庆市铜梁区白龙大道龙腾盛世"},
headers={"X-API-Key": API_KEY},
timeout=30,
)
data = resp.json()
if data["code"] == 0:
d = data["data"]
print(d["name"], d["phone"], d["address"])
print(d["province"], d["provinceCode"], d["city"], d["cityCode"],
d["district"], d["districtCode"])
JavaScript(浏览器 / Node 18+)
const resp = await fetch("https://api.xujian.tech/openapi/address/parse", {
method: "POST",
headers: { "Content-Type": "application/json", "X-API-Key": API_KEY },
body: JSON.stringify({ text: "张三,13020260925,重庆市铜梁区白龙大道龙腾盛世" }),
});
const { code, msg, data } = await resp.json();
if (code === 0) {
console.log(data.name, data.phone, data.address, data.districtCode);
} else {
console.warn("解析失败(不收费):", msg);
}
常见问题(FAQ)
address.parse 接口怎么收费?
address.parse 的收费类型为 PER_CALL(按次计费),当前单价 0.0200 元/次,调用前校验余额,余额不足返回「余额不足,请先充值。可联系微信xujian_cq」且不扣费;充值可可联系微信xujian_cq。扣费金额、交易前后余额均记录于交易流水中。
解析失败会扣费吗?
不会。本接口采用「先预鉴权、业务成功后再扣费」的两段式流程:
text 为空、超过 200 字、大模型不可用,或者识别不出地址 / 省级行政区时,
接口直接返回失败,不扣费、不写扣费流水、不累加调用次数。
只有真正返回了省级(含)以上结果,才计一次费用。
直辖市怎么返回?
北京 / 天津 / 上海 / 重庆 没有「地级市」这一层,市级名称与省级一致(都返回「重庆市」等),
市级 adcode 取省级代码(北京市 110000、天津市 120000、上海市 310000、重庆市 500000);
区县在该直辖市范围内匹配,例如「重庆市铜梁区白龙大道」返回
district=铜梁区、districtCode=500151。
大模型返回的省名和数据库不一致(如返回「四川」而不是「四川省」)怎么办?
接口内置名称规范化:比对前先去掉「省 / 市 / 自治区 / 特别行政区 / 自治州 / 自治县 / 县 / 区 / 旗 / 地区 / 盟」 等后缀,并提供「原文包含」「拼音包含」两级模糊兜底, 因此「四川」↔「四川省」、「新疆」↔「新疆维吾尔自治区」、「内蒙」↔「内蒙古自治区」都能正确匹配到同一条数据。 匹配到的结果一律返回库内规范名称与 adcode。
地址里没写区县 / 没写市,会返回什么?
未识别到的层级返回空字符串(不是 null),已识别的层级照常返回; 地址文字由已识别层级 + 详细地址拼接,不会凭空补全文本里没有的行政区。 若区县未识别但市 / 省已识别,本次调用正常计费。
姓名和电话识别不准怎么办?
提示词要求模型「不确定就留空」,并对抽取结果做了过滤(含数字 / 字母、含省市路号等地址词、 超过 20 字都会判为无效并返回空字符串),宁可留空也不会返回明显错误的值。 若业务强依赖姓名 / 电话,建议在客户端做二次校验。
单次能解析多长的文本?可以批量吗?
单条 text 最大 200 个字符,超出直接返回失败且不计费。
当前一次调用只解析一条地址,批量场景请在本地拆分后逐条调用(建议加并发控制与结果缓存)。
接口耗时大概多少?
接口需要调用一次大模型,耗时通常在 1 ~ 5 秒(响应体 costMs 为真实耗时),
明显慢于纯数据库查询类接口。建议设置 30 秒以上的客户端超时,
对时延敏感的场景改为异步调用并做好重试与缓存。
行政区划数据多久更新一次?
与 region.query 同源, 每周日凌晨 03:00 全量同步一次,管理端也支持手动立即同步; 同步采用「新增 / 更新 / 逻辑删除」比对策略,历史数据不会被物理删除。
调用需要签名或加密吗?
不需要。XAPI 的接口仅校验请求头 X-API-Key,不做签名、时间戳或加密。