ARTICLE DETAIL

资讯详情

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

历史订单地址清洗 API:批量补齐省市区、adcode 与邮编

历史订单地址清洗 API:批量补齐省市区、adcode 与邮编 历史订单地址清洗 API批量补齐省市区、adcode 与邮编电商、快递、本地生活系统里都躺着一批「野生地址」用户从聊天窗口粘过来的一整段文本姓名、电话、省市区、门牌号全挤在一行有的写简称有的漏区县有的还带「*#」分隔符。要做区域报表、运费模板、配送范围校验第一步就得把它们拆开、对齐成标准行政区划。address.parse专门做这件事输入一段中文文本输出姓名、电话、省 / 市 / 区县三级规范名称与 6 位 adcode、详细地址、邮政编码。解析不出省级行政区时不收费适合存量数据批量治理。api.xujian.techVxujian_cq接口速览关键事实说明接口地址https://api.xujian.tech/openapi/address/parse接口编码address.parse请求方式GETtext放 Query或 POSTtext放 JSON body两者等价鉴权方式请求头X-API-Key不做签名、时间戳或加密唯一业务参数text最大 200 字符返回核心字段name/phone/province/city/district/ 各级Code/detail/zipCode计费方式按次计费0.02 元/次先预鉴权、解析成功后再扣费不计费场景text为空或超长、服务暂时不可用、识别不出省级行政区计费触发点返回省级含以上结果即计一次与是否识别出区县、姓名无关单次耗时1 ~ 5 秒含一轮语义抽取costMs为真实耗时数据更新行政区划底库每周同步更新一、哪些业务需要这一步场景具体用法存量订单地址治理几万到几十万条历史地址批量结构化补齐 adcode 后才能做区域统计运费模板匹配用区县districtCode或zipCode匹配承运商分区报价配送范围校验判断收件区县是否在门店 / 前置仓覆盖范围内区域销售报表按cityCode前缀聚合不再依赖地名字符串匹配面单 OCR 后处理OCR 出来的地址文本丢进来直接得到可入库的结构化字段客服工单提取从留言、会话记录里抽取地址并落库下单页智能填充用户粘贴整段地址前端拆成表单字段并回填三级联动会员地址归一化同一收件人的不同写法归一到同一组 adcode便于合并去重反欺诈辅助核验比对下单地址与常用收货地是否一致用户地域画像按省市区统计客户分布支撑选品与投放二、请求参数2.1 请求头参数名必填说明X-API-Key是开发者 API Key缺失或无效直接返回失败Content-TypePOST 时必填固定application/json否则 body 里的text取不到2.2 业务参数参数名必填类型示例说明text是String张三13020260925重庆市铜梁区白龙大道龙腾盛世待解析文本可含姓名、电话、地址顺序不限最大 200 字符换行、制表符会归一为空格服务端先取 Query 里的text为空再取 JSON body 里的text。三、返回字段3.1 顶层字段类型说明codeint0成功非 0 失败统一为500msgString成功为success失败为具体原因dataObject业务数据失败时为null3.2 data 字段字段类型示例说明nameString张三收件人姓名识别不到为空字符串不会是 nullphoneString13020260925电话只保留数字识别不到为空字符串addressString重庆市铜梁区白龙大道龙腾盛世用库内规范名拼接的「省 市 区县 详细地址」provinceString重庆市省级规范名称如「四川省」「内蒙古自治区」provinceCodeString500000省级 6 位 adcodecityString重庆市地市名称直辖市返回直辖市名识别不到为空字符串cityCodeString500000地市级 adcode识别不到为空字符串districtString铜梁区区 / 县名称识别不到为空字符串此时仍返回省 / 市districtCodeString500151区县级 adcode省直辖县级为 9 位如419001000detailString白龙大道龙腾盛世详细地址去掉省市区后的道路、门牌、小区等原文zipCodeString402500邮政编码匹配到区县时带回未匹配到为空字符串apiCodeStringaddress.parse接口编码apiNameString地址信息解析接口名称chargeTypeStringPER_CALL计费类型balanceBigDecimal99.9800扣费后的账户余额元costMsLong1820耗时毫秒覆盖鉴权 解析 扣费全链路3.3 姓名与电话的清洗规则字段规则结果name去空白长度 20 或含数字 / 字母 → 丢弃含「省 / 市 / 区 / 县 / 镇 / 路 / 街 / 号 / 栋 / 单元 / 楼 / 小区 / 大厦 / 驿站」等地址词 → 丢弃空字符串phone只保留数字13 位且以86开头则剥掉86长度 7 或 11 → 丢弃空字符串3.4 直辖市口径直辖市province / cityprovinceCode / cityCode北京市北京市110000天津市天津市120000上海市上海市310000重庆市重庆市500000注意data不含keyword字段写解析代码时不要照抄企业系列接口的取法。四、调用示例4.1 curl# GETcurl-s-Ghttps://api.xujian.tech/openapi/address/parse\--data-urlencodetext张三13020260925重庆市铜梁区白龙大道龙腾盛世\-HX-API-Key: 你的APIKey# POSTcurl-s-XPOSThttps://api.xujian.tech/openapi/address/parse\-HX-API-Key: 你的APIKey\-HContent-Type: application/json\-d{text:张三13020260925重庆市铜梁区白龙大道龙腾盛世}4.2 JavaHutoolimportcn.hutool.http.HttpRequest;importcn.hutool.json.JSONObject;importcn.hutool.json.JSONUtil;publicclassAddressParseClient{privatestaticfinalStringAPI_URLhttps://api.xujian.tech/openapi/address/parse;/** * 解析中文地址文本 * * param apiKey 开发者 API Key * param text 待解析文本最大 200 字符 * return data 节点解析失败返回 null且不收费 */publicstaticJSONObjectparse(StringapiKey,Stringtext){JSONObjectjsonJSONUtil.parseObj(HttpRequest.post(API_URL).header(X-API-Key,apiKey).body(JSONUtil.createObj().set(text,text).toString()).timeout(20000).execute().body());if(json.getInt(code)null||json.getInt(code)!0){System.out.println(解析失败不收费json.getStr(msg));returnnull;}returnjson.getJSONObject(data);}publicstaticvoidmain(String[]args){JSONObjectdataparse(你的APIKey,张三13020260925重庆市铜梁区白龙大道龙腾盛世);if(datanull){return;}System.out.printf(%s %s %s %s%n,data.getStr(provinceCode),data.getStr(cityCode),data.getStr(districtCode),data.getStr(zipCode));}}4.3 Pythonimportrequestsdefaddress_parse(api_key:str,text:str):返回 data 节点解析失败返回 None且不收费resprequests.post(https://api.xujian.tech/openapi/address/parse,json{text:text},headers{X-API-Key:api_key},timeout20,)resultresp.json()ifresult.get(code)!0:print(解析失败不收费,result.get(msg))returnNonereturnresult[data]if__name____main__:print(address_parse(你的APIKey,李四 13800138000 四川省成都市郫都区红光镇家园路88号))4.4 JavaScriptasyncfunctionaddressParse(apiKey,text){constrespawaitfetch(https://api.xujian.tech/openapi/address/parse,{method:POST,headers:{X-API-Key:apiKey,Content-Type:application/json},body:JSON.stringify({text})});constresultawaitresp.json();if(result.code!0){thrownewError(result.msg);}returnresult.data;}五、返回示例直辖市地址{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}}只写到市区县与邮编返回空字符串{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}}省直辖县级行政区districtCode为 9 位{code:0,msg:success,data:{name:王五,phone:13900139000,address:河南省济源市黄河大道88号,province:河南省,provinceCode:410000,city:济源市,cityCode:419001,district:济源市,districtCode:419001000,detail:黄河大道88号,zipCode:459000,apiCode:address.parse,apiName:地址信息解析,chargeType:PER_CALL,balance:99.9200,costMs:1670}}解析失败不收费{code:500,msg:未能从文本中识别出有效地址至少需要能定位到省级行政区请补充更完整的地址后重试本次调用不计费,data:null}六、可直接复用的两段代码6.1 批量清洗 进度保存importjsonimporttimeimportrequestsdefbatch_clean(api_key:str,rows,out_file:str,sleep:float0.2):rows: [{id: 1, raw: 张三 130... 重庆市...}, ...]断点续跑doneset()try:withopen(out_file,encodingutf-8)asf:forlineinf:done.add(json.loads(line)[id])exceptFileNotFoundError:passwithopen(out_file,a,encodingutf-8)asf:forrowinrows:ifrow[id]indone:continuedataaddress_parse(api_key,row[raw][:200])ifdata:f.write(json.dumps({id:row[id],province_code:data[provinceCode],city_code:data[cityCode],district_code:data[districtCode],zip_code:data[zipCode],detail:data[detail],},ensure_asciiFalse)\n)f.flush()time.sleep(sleep)6.2 清洗质量统计defquality_report(results):results 为清洗结果列表统计各级命中率totallen(results)or1defhit(key):returnsum(1forrinresultsifr.get(key))/totalreturn{province:hit(province_code),city:hit(city_code),district:hit(district_code),zip:hit(zip_code),}七、实践建议超长文本先本地截断。text上限 200 字符超了直接失败且不收费批量任务里先切到 200 再发。用districtCode做外键不要用地名。地名有简称、别名adcode 稳定。空字符串要兜底。区县、邮编经常为空用户没写下游逻辑别假设一定有值。9 位代码要留够字段长度。省直辖县级行政区如济源市的districtCode是 9 位。失败要分类。解析不出省级行政区是数据问题服务超时是可用性问题两类应该分别统计、分别重试。批量任务加缓存。同一地址文本重复出现很常见先查本地缓存能省不少调用。1 ~ 5 秒的耗时要有预期。含一轮语义抽取批量任务建议低并发 退避重试。结果存原始文本。保留raw与解析结果方便以后口径升级后重跑。八、错误码与排查codemsg是否扣费0success扣费识别出省级及以上即计一次500缺少请求头 X-API-Key否500API Key 无效 / API Key 已停用否500客户不存在或已停用否500接口不存在或已停用否500余额不足请先充值否500text 不能为空GET 传 Query 参数POST 传 JSON {“text”:“…”}否500text 长度不能超过 200 个字符否500未能从文本中识别出有效地址至少需要能定位到省级行政区请补充更完整的地址后重试本次调用不计费否500地址解析服务暂时不可用请求大模型超时或网络异常本次调用不计费否500调用上下文无效请重新发起请求否九、计费与接入项目说明单价0.02 元/次计费方式按次计费调用前校验余额先预鉴权解析成功后才扣费不计费场景参数为空 / 超长、服务暂时不可用、识别不出省级行政区计费触发点返回省级含以上结果即计一次与是否识别出区县、姓名无关频率限制当前未做硬性限流高频场景建议本地缓存接入流程注册开发者账号 → 控制台创建 API Key → 请求头带上X-API-Key即可调用无需签名或加密。控制台可查看调用量、扣费流水与余额。服务站点api.xujian.tech纯文本域名不做跳转。接口试用、数据与充值咨询可在控制台提交工单或Vxujian_cq。十、小结地址清洗的价值不在「拆字段」而在拆完之后能按区域做统计、匹配运费、判断配送范围。address.parse的几个关键取舍解析不出省级不收费批量治理脏数据时失败不产生成本字段口径统一三级名称 6 位 adcode 邮编直接落库当维表用GET / POST 都支持批量脚本用 POST前端表单用 GET不用改服务端空值是空字符串不是 null解析代码里判断要统一别写成is None。如果只想要标准行政区划数据本身不含姓名电话可以搭配行政区划查询接口region.query免费使用用它做本地底库用本接口做文本解析。
返回列表