二手车车源信息查询 API 实战车型、图片、里程、首付与标签批量拉取做二手车选品、车源同步、行情分析时第一步往往卡在「没有数据」公开平台的车源列表是动态渲染的车型名称、图片、里程、首付、标签混在一堆 HTML 里自己抓要处理分页、懒加载、反爬。本文介绍一个二手车车源信息查询接口一次 GET 请求返回当前可查的车源列表车型名称、图片链接、行驶里程、注册年份、首付价格、车辆标签一次拿全且无车源返回时不收费。api.xujian.techVxujian_cq一、车源数据显示场常见的几个坑难点具体表现数据是渲染出来的车源列表走 JS 动态加载HTML 里只有空壳直接抓页面拿不到数据分页与懒加载图片滚动到底才加载分页接口往往带签名逆向成本很高字段不规范车型名称是「长安启源E07 2025款 纯电 两驱 90kWh Max智驾版」这种长文本年款、配置、续航都挤在一起里程单位混乱有的写「3.2万公里」有的写「32000」有的写「3.2」无单位首付价格口径不一「首付 3.8万」可能是月供也可能是首付总额数据量不可控一次拉回上千条存储和渲染都吃不消把这一步收敛成一个接口价值在于字段已经清洗好里程统一为万公里数值文本、首付统一为万元、regDate统一为「年份」文本、标签已经是数组并且可以用limit控制返回条数。二、接口能力概览2.1 接口基础信息项目说明接口地址https://api.xujian.tech/openapi/usedcar/list接口编码usedcar.list请求方式GETlimit放 Query String鉴权方式请求头X-API-Key不做签名、时间戳或加密返回格式JSONContent-Type: application/json;charsetUTF-8单次费用0.01 元/次最多返回50 条limit缺省即上限是否需要业务入参否只有可选的limit典型耗时数百毫秒 ~ 数秒响应体costMs字段为本次真实耗时在线文档https://api.xujian.tech/api/usedcar-list2.2 请求参数请求头参数名必填说明X-API-Key是开发者 API Key缺失或无效直接返回失败业务参数参数名必填类型示例说明limit否Integer20期望返回条数取值范围 1 ~ 50缺省按上限 50 返回传0或负数按上限处理这个接口没有筛选入参品牌 / 价格 / 里程等筛选需要在调用侧自己做。设计上它是「一次拉全量、本地再筛选」的模式单次最多 50 条本地过滤远比在接口上堆一堆分不清的筛选参数省心。2.3 计费上比较实在的一点接口是先预鉴权、查到结果后再扣费的两段式流程。下面这些情况直接返回失败不扣费、不写扣费流水、不累加调用次数上游数据服务暂时不可用超时或网络异常当前没有可查车源上游返回空列表。也就是说只有真正返回了至少一条车源才计一次费用。做定时任务同步时服务异常或空结果不会白白吃掉预算。三、返回字段详解3.1 顶层字段字段类型说明codeint0成功非 0 失败常见为500msgString结果描述成功为success失败为具体原因dataObject业务数据失败时为null3.2 data 字段字段类型示例说明totalint20本次实际返回的车源条数listArray[…]车源列表apiCodeStringusedcar.list接口编码apiNameString二手车信息查询接口名称chargeTypeStringPER_CALL计费类型balanceBigDecimal99.9800调用完成后已扣费的账户余额元costMsLong1120本次调用耗时毫秒注意本接口返回的data不含keyword没有业务入参与企业系列接口的返回结构略有差异解析时别写死取keyword。3.3 list[] 车源对象字段字段类型示例说明carNameString长安启源E07 2025款 纯电 两驱 90kWh Max智驾版车型名称含品牌、年款、配置版本imageUrlStringhttps://…/car.jpg车辆图片链接可直接用于img srcmileageString3.20行驶里程单位万公里纯数值文本regDateString2024年车辆注册年份downPaymentString3.80首付价格单位万元纯数值文本tagsArray[“新上架”,“准新车”,“0次过户”]车辆标签数组常见的tags取值新上架 / 准新车 / 0次过户 / 原厂质保 / 个人一手 / 支持分期 / 7天无理由退车 等属于平台运营标签会随车源动态变化业务侧建议做白名单翻译而非硬编码全部枚举。两个字段设计上的细节一是mileage/downPayment是不带单位的数值文本3.20表示 3.2 万公里、3.80表示 3.8 万元拼接展示时自己补单位二是上游的内部数据主键dataId/dId/cid不对外返回需要唯一标识时建议使用carNameregDatemileage组合键。四、调用示例4.1 curl# 拉满 50 条curl-s-Ghttps://api.xujian.tech/openapi/usedcar/list\-HX-API-Key: 你的APIKey# 只要 20 条curl-s-Ghttps://api.xujian.tech/openapi/usedcar/list\--data-urlencodelimit20\-HX-API-Key: 你的APIKey4.2 JavaHutoolimportcn.hutool.http.HttpRequest;importcn.hutool.json.JSONArray;importcn.hutool.json.JSONObject;importcn.hutool.json.JSONUtil;publicclassUsedCarListClient{privatestaticfinalStringAPI_URLhttps://api.xujian.tech/openapi/usedcar/list;/** * 查询二手车车源列表 * * param apiKey 开发者 API Key * param limit 期望返回条数1 ~ 50传 null 取上限 * return 车源列表无车源或查询失败返回 null且不扣费 */publicstaticJSONArraylist(StringapiKey,Integerlimit){HttpRequestreqHttpRequest.get(API_URL).header(X-API-Key,apiKey).timeout(20000);if(limit!nulllimit0){req.form(limit,limit);}JSONObjectjsonJSONUtil.parseObj(req.execute().body());Integercodejson.getInt(code);if(codenull||code!0){System.out.println(查询失败不收费json.getStr(msg));returnnull;}returnjson.getJSONObject(data).getJSONArray(list);}publicstaticvoidmain(String[]args){JSONArraylistlist(你的APIKey,20);if(listnull){return;}for(inti0;ilist.size();i){JSONObjectclist.getJSONObject(i);System.out.printf(%s | %s万公里 | %s | 首付 %s万%n,c.getStr(carName),c.getStr(mileage),c.getStr(regDate),c.getStr(downPayment));}}}4.3 Pythonimportrequestsdefusedcar_list(api_key:str,limit:int50): 查询二手车车源列表 Args: api_key: 开发者 API Key limit: 期望返回条数1 ~ 50 Returns: list: 成功返回车源列表无车源或失败返回 None且不扣费 resprequests.get(https://api.xujian.tech/openapi/usedcar/list,params{limit:limit},headers{X-API-Key:api_key},timeout20,)resultresp.json()ifresult.get(code)!0:print(查询失败不收费,result.get(msg))returnNonereturnresult[data][list]if__name____main__:forcarinusedcar_list(你的APIKey,20)or[]:print(car[carName],car[mileage],car[regDate],car[tags])4.4 JavaScript浏览器 / Node 18constrespawaitfetch(https://api.xujian.tech/openapi/usedcar/list?limit20,{headers:{X-API-Key:API_KEY},});const{code,msg,data}awaitresp.json();if(code0){data.list.forEach((car){console.log(car.carName,${car.mileage}万公里,car.tags.join(/));});}else{console.warn(查询失败不收费,msg);}五、返回示例5.1 成功返回{code:0,msg:success,data:{total:3,list:[{carName:长安启源E07 2025款 纯电 两驱 90kWh Max智驾版,imageUrl:https://example.com/car/e07-1.jpg,mileage:0.50,regDate:2025年,downPayment:5.60,tags:[新上架,准新车,0次过户,原厂质保]},{carName:大众迈腾 2021款 330TSI DSG 豪华型,imageUrl:https://example.com/car/magotan-1.jpg,mileage:3.20,regDate:2021年,downPayment:3.80,tags:[个人一手,支持分期]},{carName:丰田凯美瑞 2019款 2.5G 豪华版,imageUrl:https://example.com/car/camry-1.jpg,mileage:6.80,regDate:2019年,downPayment:2.90,tags:[7天无理由退车]}],apiCode:usedcar.list,apiName:二手车信息查询,chargeType:PER_CALL,balance:99.9800,costMs:1120}}5.2 无可用车源不收费{code:500,msg:未查询到可用车源请稍后重试本次调用不计费,data:null}六、典型应用场景6.1 车源同步落库含去重键由于没有返回业务主键落库时用组合键去重defsync_cars(api_key:str,db:dict,limit:int50)-int:把车源同步到本地字典返回新增条数carsusedcar_list(api_key,limit)or[]added0forcarincars:# 车型 年份 里程 组合作为去重键keyf{car[carName]}|{car[regDate]}|{car[mileage]}ifkeynotindb:db[key]car added1returnadded图片链接建议不要长期外链第三方图床随时可能失效或加防盗链同步时把图片下载到自己的对象存储更稳。6.2 本地筛选替代接口筛选参数接口没提供筛选入参但总数据量最多 50 条本地过滤完全够functionpick(cars,{maxMileage,minYear,maxDownPayment,tags}){returncars.filter((c){constyearNumber(String(c.regDate).replace(年,));constmileageNumber(c.mileage);constpayNumber(c.downPayment);return((!maxMileage||mileagemaxMileage)(!minYear||yearminYear)(!maxDownPayment||paymaxDownPayment)(!tags||tags.some((t)c.tags.includes(t))));});}6.3 车型名称结构化carName是长文本展示前通常要拆出品牌、年款、配置三段privatestaticString[]splitCarName(StringcarName){// 长安启源E07 2025款 纯电 两驱 90kWh Max智驾版 →// [品牌车型前缀, 2025款, 剩余配置描述]String[]partscarName.split( ,3);String[]arrnewString[3];arr[0]parts.length0?parts[0]:;// 长安启源E07arr[1]parts.length1?parts[1]:;// 2025款arr[2]parts.length2?parts[2]:;// 纯电 两驱 90kWh Max智驾版returnarr;}品牌字典可以用这张拆分结果去建把第一段与已知品牌表做前缀匹配即可。6.4 行情统计首付与里程分布fromcollectionsimportCounterdefstats(api_key:str,limit:int50)-dict:按注册年份统计车源数量与平均首付carsusedcar_list(api_key,limit)or[]by_yearCounter(c[regDate]forcincars)pays[float(c[downPayment])forcincarsifc.get(downPayment)]return{byYear:dict(by_year),avgDownPayment:round(sum(pays)/len(pays),2)ifpayselse0,}七、提升可用性的几条实践建议limit别贪心。上限 50 条实际场景选品抽查、行情抽样用 20 ~ 30 条足够还能省带宽与解析开销。数值字段已统一单位。mileage万公里、downPayment万元直接Float.parseFloat即可不要再去解析单位文本。图片尽快转存。第三方图片链接有防盗链与过期风险展示型业务建议同步时转存到自己的 OSS。标签做白名单翻译。tags是运营标签、会动态增减未知标签直接原样展示比写死枚举好。定时任务做好幂等。没有业务主键务必用组合键carNameregDatemileage去重。区分「无车源」与「服务异常」。前者是未查询到可用车源……本次调用不计费后者是数据服务暂时不可用……重试策略应不同。八、错误码与排查codemsg示例处理建议0success调用成功500缺少请求头 X-API-Key在请求头补充X-API-Key500API Key 无效 / API Key 已停用检查 Key 是否正确或在控制台重新启用500客户不存在或已停用联系平台确认账号状态500接口不存在或已停用确认usedcar.list当前是否维护中500余额不足请先充值按次计费接口调用前校验余额余额不足不扣费充值后重试500未查询到可用车源……上游暂无车源稍后重试不计费500二手车服务未启用 / 二手车服务未配置上游凭证缺失平台侧配置问题稍后重试不计费500数据服务暂时不可用请求上游超时或网络异常稍后重试不计费九、计费与接入项目说明单次费用0.01 元/次计费方式按次计费调用前校验余额返回车源后才扣费不计费场景服务暂时不可用、上游返回空车源列表返回条数最多 50 条用limit收敛接入流程注册开发者账号 → 控制台创建 API Key → 请求头带上X-API-Key即可调用无需签名或加密。控制台可查看调用量、扣费流水与余额。控制台地址https://api.xujian.tech接口接入、数据与充值相关问题可联系微信xujian_cq。十、总结车源数据的难点从来不在算法而在「拿到干净的结构化数据」这一层。这个接口的价值就是把渲染型页面里最难处理的部分——车型长文本、图片链接、里程与首付的单位统一、动态运营标签——提前处理好调用方拿到 JSON 就能直接入库或渲染。几个关键取舍值得留意无车源不收费定时任务遇到空结果不会产生费用单位收敛到字段语义mileage万公里、downPayment万元都是可直接 parse 的数值文本不放一堆看不懂的筛选参数总数据量上限 50 条本地过滤比堆接口参数更灵活内部标识不外传上游dataId/cid等主键不返回避免调用方依赖一个随时可能变的内部约定。