做开发这些年我手机备忘录里一直躺着一个分组名字就叫“API接口收藏”。里面塞满了各种免费接口的地址、文档链接和备用 Key写脚本缺数据了翻一翻做 demo 少功能了找一找可以说是我的隐形工具箱。今天这篇就把我筛选过、实际用过、目前还能跑的常用免费 API 接口整理出来涵盖数据查询、AI 大模型、翻译、微信生态这几个高频方向顺便把申请 Key、调用鉴权、限流避坑这些经验一并写上。不管你是刚学接口调用的新人还是做全栈项目的老手这份清单都能帮你少走不少弯路。先说清楚一个事免费接口不等于随手拿来就能用。很多接口有 QPS 限制、有每日调用上限、有返回字段变动风险选型的时候不看清楚等上了生产环境才发现问题那才叫一个头大。所以我下面每类接口都会讲清楚它适合干什么、不适合干什么以及我在真实项目里踩过的坑。1. 免费 API 接口的价值与选型逻辑1.1 一份常用清单能解决什么问题很多人觉得 API 接口是后端工程师才需要关心的东西其实不是。前端要联调 Mock 数据客户端要接入地图和推送数据分析师要抓行情和天气就连写自动化脚本的运维都得天天跟接口打交道。我见过不少非技术背景的同事为了拿到一组图书信息或者快递轨迹宁可去网页上手动复制粘贴也不愿意花十分钟调一个免费接口原因就是不知道去哪找、不知道怎么用。这份清单解决的就是“去哪找、怎么用、怎么避坑”三件事。以我自己的使用频率来看最常用的其实就那么十几个ISBN 查图书、股票查行情、天气查预报、翻译查词句、大模型做文本处理、微信接口做消息通知。把这些常用方向梳理清楚比收藏一堆五花八门但实际用不上的接口有价值得多。另外说句实在话免费接口在个人项目、学习 demo、内部工具里完全够用。付费接口的优势主要体现在 SLA 保障、并发上限和客服支持上但如果你做的是博客站、学习项目、个人助理脚本免费额度通常绰绰有余。1.2 选免费接口时的四个判断标准我不建议看到一个免费接口就赶紧收藏收藏之前先拿四个标准过一遍文档是否完整有没有清晰的请求示例、参数说明、返回字段说明。文档都写不清楚的接口调用起来大概率也得靠猜。调用限制是否明确免费版 QPS 是多少、每日上限是多少、超出之后是报错还是直接熔断。有些接口超出限制后直接封 Key连申诉渠道都没有。返回格式是否稳定响应是 JSON 还是 XML字段命名是否规范有没有版本变更历史。我在实战里见过返回字段说变就变的接口前端直接崩一片。Key 的申请成本有些平台申请 Key 要审核一两天有些注册完秒发。做快速验证的时候申请成本越低越好。把这四个标准列出来之后你再看任何免费接口心里都有数了。免费东西的代价往往是限速和不确定性这个不是坏事只要你提前把它当做一个不可靠组件来设计反而用得很稳。2. 数据查询类 APIISBN、股票、天气、快递2.1 ISBN 图书信息查询接口怎么用ISBN 这玩意儿看着就是一串数字但背后对应了书名、作者、出版社、封面图、出版日期一堆信息。做图书管理系统、二手书交易平台、个人书单工具的时候最烦的就是手动录书。我最早是手动建了一个数据库表一本一本往里填效率低到爆炸后来改用 ISBN 查询接口扫个码或者输入一串数字信息就自动带出来了。目前可用的 ISBN 查询方案主要有两类。一类是综合性 API 平台提供的图书接口比如聚合数据、极速数据这些注册之后申请对应的图书 API拿到 Key 就能调。这类平台的优点是文档规范、返回字段丰富缺点是有每日调用次数限制免费版通常每天几十到几百次个人项目够用商用就得考虑付费。另一类是一些开放的图书数据库接口。以我常用的一个方案为例请求方式类似这样curl https://api.example.com/isbn/query?isbn9787111213826appkey你的key返回内容大致是这种结构{ isbn: 9787111213826, title: 代码大全, author: Steve McConnell, publisher: 电子工业出版社, pubdate: 2006-03-01, cover: https://... }拿到返回之后前端直接把title、author、cover这几个字段渲染出来就行。这里有个经验不要只用一个 ISBN 数据源。图书数据的覆盖面各家不一样有些书在这个平台查得到在那个平台就是空的。我一般会配置两个数据源第一个查不到就降级到第二个两个都没有再提示用户手动补充。这种多源降级的设计在免费接口场景里特别重要因为免费数据源谁也没法保证 100% 覆盖。2.2 股票行情接口的快与坑股票数据是免费接口里比较特殊的一类。说特殊是因为行情数据对实时性要求极高但真正实时的接口都是收费的免费接口通常有延迟而且行情数据的稳定性直接关系到资金决策用免费接口必须格外谨慎一定不能把它作为唯一数据源去支撑实盘交易。国内常见的免费行情来源一个是新浪财经的公开接口另一个是腾讯财经的行情接口。它们通过 HTTP 返回文本或 JSON 数据调用方式在技术社区里都有现成的封装代码。以新浪为例请求某个股票的实时报价地址大概是curl https://hq.sinajs.cn/listsh600000返回的内容是 GBK 编码的文本包含了股票名称、今开、昨收、当前价、最高、最低等字段。需要注意两点第一这个接口现在对 Referer 有要求直接 curl 不带模拟请求头可能拿不到数据第二返回编码不是 UTF-8解析的时候要做编码转换Python 里用resp.content.decode(gbk)才能正确显示。腾讯的行情接口类似返回的是 JSONP 格式需要做一层字符串处理才能转成 JSON 对象。两个接口的刷新频率都不能太高我个人一般是 5 秒到 10 秒拉一次再频繁就容易触发限制。再强调一遍这类接口适合做学习研究、个人盯盘提醒、非实时的行情展示不适合用于量化交易下单。真要做交易系统必须用券商或正规数据商提供的合规接口。2.3 天气与快递这类生活服务接口天气和快递查询是免费接口里“性价比”最高的两类。生活类应用、自动化通知脚本、智能家居控制台都会用到。天气接口我比较推荐和风天气的免费版。它注册后就能拿 Key免费版支持实况天气和逐小时预报QPS 和每日调用量对个人项目来说相当充裕。请求方式很简单curl https://devapi.qweather.com/v7/weather/now?location101010100key你的key参数里location是城市 ID可以是经纬度也可以是城市代码返回数据里有温度、体感温度、风向、风速、湿度这些字段。和风的文档做得比较规范字段命名也清晰对新手友好。快递查询接口聚合数据、快递鸟、快递100都有免费额度。它们的特点是需要你在后台申请对应快递公司的授权然后通过接口传入快递单号返回物流轨迹。我实际用的感受是免费版要么有单号查询次数限制要么只支持部分快递公司用之前先看清楚支持列表别等上线了才发现中通查不了。3. AI 大模型接口豆包、Groq 与开源项目的 API 化3.1 豆包 API 的调用方式豆包在 C 端产品里是一个聊天助手但作为开发者你真正要关心的是它背后的 API 接口。豆包的 API 在火山方舟平台上申请进入方舟控制台创建推理接入点之后系统会给你一个 API Key 和对应的模型 ID。调用方式上豆包 API 兼容 OpenAI 的接口格式。这意味着什么意味着你不用专门去学一套新的 SDK直接用你熟悉的openaiPython 库或者任何兼容 OpenAI 的 HTTP 客户端就能调。一个典型的请求长这样curl https://ark.cn-beijing.volces.com/api/v3/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer 你的APIKey \ -d { model: doubao-pro-32k, messages: [ {role: user, content: 用一句话介绍 API 接口是什么} ] }返回结果里的choices[0].message.content就是模型生成的文本。我个人的体会是豆包在中文理解和日常对话场景下表现不错生成速度快免费额度对个人开发者来说也比较友好。这里给个建议在方舟控制台里开通模型服务之后把 API Key 放在环境变量里别硬编码到项目代码中。免费额度是跟着账号走的Key 一旦泄露被刷光很麻烦。3.2 Groq 免费接口的定位Groq 在技术圈里火起来靠的是两个字快。它提供的推理服务延迟极低特别适合对响应速度敏感的场景比如聊天机器人、代码补全、实时翻译。Groq 有一套自己的模型服务同时也提供兼容 OpenAI 格式的接口。使用流程大致是到 Groq 官网注册账号创建一个 API Key然后在请求的时候把base_url指向https://api.groq.com/openai/v1模型名称填入类似llama-3.3-70b-versatile这样的标识。用 Python 的 openai 库可以直接这样写from openai import OpenAI client OpenAI( api_key你的groq_key, base_urlhttps://api.groq.com/openai/v1 ) resp client.chat.completions.create( modelllama-3.3-70b-versatile, messages[{role: user, content: 你好介绍一下你自己}] ) print(resp.choices[0].message.content)需要注意Groq 的免费额度有请求速率和每日上限具体数值会调整用之前先到控制台看一眼当前限制。另外它的服务器在海外实际访问是否流畅跟你的本地网络环境直接相关用之前自己先测一下响应延迟。如果网络条件不理想可以考虑用国内其他提供兼容接口的大模型平台效果差不多。3.3 FaceFusion 这类开源项目没有官方 API 怎么办有段时间不少人在搜“FaceFusion 官方提供 API 接口了吗”我直接说结论FaceFusion 本身是一个命令行工具官方的重点放在推理效果上并没有像商业产品那样提供标准化的 REST API。想把它集成到自己的服务里常见的做法是自己包一层 API。这种“给开源项目包一层 API”的做法适用于很多类似项目。思路很简单项目本身是 Python 写的你就用 FastAPI 起一个 HTTP 服务把项目的核心推理函数封装成 POST 接口。客户端上传一张图片或一段视频服务端调用项目内部的推理流程再把处理结果返回。from fastapi import FastAPI, UploadFile from facefusion import core app FastAPI() app.post(/api/process) async def process_image(file: UploadFile): input_path save_temp(file) output_path core.process(input_path) return {result_url: f/output/{output_path}}上面这段是示意代码实际封装时要处理文件上传大小限制、任务队列、GPU 资源分配这些问题。同时也要提醒一句深度合成类的技术在做人脸替换、声音克隆这类功能时一定要遵守内容安全规范只做合法合规的正向场景不能在未经授权的情况下处理他人肖像更不能拿去制作恶搞或欺诈内容。4. 翻译、微信与 Java 调用场景4.1 搜狗翻译 API 的正确打开方式搜狗翻译的免费接口在个人翻译工具、多语言内容采集脚本里都挺实用。搜狗翻译有一个开放的 API 平台注册后可以申请翻译接口。它和前面说的那些 Key 直传接口稍微有点区别搜狗翻译的 API 要求对请求做签名调用前需要准备appid和secret然后把请求参数排序拼接、做 HMAC 或者 MD5 签名再把签名结果一起传给接口。流程听着复杂其实很多语言都有现成的 SDK 或者封装包。用 Python 的话核心步骤是这么几步构造请求参数 dict加入q要翻译的文本、from、to、appid、salt随机数、sign签名结果然后用 requests 库发 POST 请求。import hashlib import requests def translate_youdao(text, appid, secret): salt 123456 sign hashlib.md5((appid text salt secret).encode()).hexdigest() resp requests.post( https://openapi.youdao.com/api, data{q: text, from: auto, to: zh-CHS, appKey: appid, salt: salt, sign: sign} ) return resp.json()[translation][0]注意上面这段用的是有道翻译的调用格式搜狗、百度翻译的思路大同小异核心都是 appid secret 签名。这里提醒一个常见误解网上有些文章会教你去抓翻译网页的公开接口就是那种不需要 Key 直接传文本就能返回翻译结果的地址。这种接口不是不能用但属于“野接口”随时可能因为页面改版或者风控升级而失效。做学习 demo 可以做正式项目我不建议老老实实走开放平台申请官方 Key 才是正道。4.2 微信生态里的常用 API 地址微信的接口是另一块高频需求。开发公众号、小程序、企业微信应用每天都要跟微信的 API 地址打交道。这里整理几个最常用的固定地址格式这些年基本没变过获取 access_tokenhttps://api.weixin.qq.com/cgi-bin/token?grant_typeclient_credentialappidAPPIDsecretAPPSECRET发送模板消息https://api.weixin.qq.com/cgi-bin/message/template/send?access_tokenACCESS_TOKEN小程序登录code2sessionhttps://api.weixin.qq.com/sns/jscode2session?appidAPPIDsecretAPPSECRETjs_codeCODEgrant_typeauthorization_codeaccess_token 是微信接口调用最关键的凭证。它的有效期是 7200 秒而且获取接口有每日调用上限千万不能每个请求都去重新拉一次。正确做法是服务启动时拉一次存到内存或 Redis 里加上过期时间快过期了再刷新。另外appsecret这种敏感信息只能保存在服务端绝不能放到小程序前端代码里。我见过有人为了图省事直接把 appsecret 写在云开发函数的配置里还提交到了 GitHub 公开仓库结果第三方机器人扫描到之后拿去发垃圾消息账号直接被封。这个坑踩一次代价就很大。4.3 Java 开发中如何把第三方接口封装给外部调用热词里有一条“java开发api接口以供外部调用”这个场景在实际工作中非常常见。很多时候第三方接口的 Key 不能暴露给前端或者你需要在调用第三方接口之前做一层参数处理、频率控制、缓存。这时候就要写一个中间层 API客户端请求你的后端接口后端再去请求第三方接口拿到结果返回给客户端。Java 后端写这种转发接口我一般用 Spring Boot RestTemplate或WebClient。一个典型的 Controller 长这样RestController RequestMapping(/api/translate) public class TranslateController { Value(${translate.appid}) private String appid; Value(${translate.secret}) private String secret; GetMapping(/text) public MapString, String translate(RequestParam String text) { // 1. 生成签名 String salt String.valueOf(System.currentTimeMillis()); String sign MD5Util.md5(appid text salt secret); // 2. 调用第三方翻译接口 RestTemplate client new RestTemplate(); MultiValueMapString, String body new LinkedMultiValueMap(); body.add(q, text); body.add(appKey, appid); body.add(salt, salt); body.add(sign, sign); MapString, Object resp client.postForObject( https://openapi.youdao.com/api, body, Map.class); // 3. 只把需要的数据返回给前端 MapString, String result new HashMap(); result.put(translation, ((List?) resp.get(translation)).get(0).toString()); return result; } }为什么要多绕一层不让前端直接调第三方原因主要有三个第一密钥安全第三方接口的 appid 和 secret 放在服务端前端永远接触不到第二统一出口前端只需要对接你的接口不用关心你用的是哪家翻译服务以后你从百度翻译换成腾讯翻译前端代码一行都不用改第三可以做缓存和限流同一个文本第二次请求直接从服务端缓存返回既省第三方额度又加快响应速度。实际开发中还要注意设置网络超时防止第三方接口长时间不返回导致线程挂死。RestTemplate默认没有超时时间必须手动配置SimpleClientHttpRequestFactory的connectTimeout和readTimeout这一点经常被新手忽略。5. 实操一套通用免费 API 调用流程5.1 申请 Key 与鉴权方式的三类主流模式免费 API 接口的鉴权方式看起来五花八门归纳起来就三类鉴权方式典型场景实现方式安全等级Header 携带 Token大多数大模型平台Authorization: Bearer token高Query 参数携带 Key天气、地图、生活服务?keyappkey中签名模式翻译、支付类接口appid secret 生成 sign高日常使用中第一类和第二类最多。我个人的习惯是如果只是快速验证接口能不能用直接把 Key 放到请求参数里简单直接如果是正式项目统一走 Header 携带 Token 的方式因为它不会出现在 URL 访问日志里相对不容易泄露。第三种签名模式安全性最高但调试成本也最高。我遇到过最典型的报错就是签名拼接顺序不对解决方案只有一条严格按照官方文档里的示例把待签名字符串完整打印出来和文档逐字比对别凭感觉猜。5.2 用 Python 封装一个通用请求器调免费接口最烦的事情是每个接口的格式都有细微差别这个要 JSON那个要表单还有一个要加签名。与其为每个接口单独写请求代码不如做一个通用请求器把超时、重试、错误码解析这些公共逻辑统一封装。import time import requests class FreeApiClient: def __init__(self, timeout10, retries3): self.timeout timeout self.retries retries self.session requests.Session() def get_json(self, url, paramsNone, headersNone): for attempt in range(self.retries): try: resp self.session.get( url, paramsparams, headersheaders, timeoutself.timeout ) resp.raise_for_status() return resp.json() except requests.exceptions.Timeout: print(f第 {attempt 1} 次请求超时) if attempt self.retries - 1: raise time.sleep(1) except requests.exceptions.JSONDecodeError: raise ValueError(f响应不是合法 JSON原始内容: {resp.text[:200]})这个类的核心精髓在两点第一超时时间必须显式设置不设超时网络一抖你的程序就挂在那边了第二对 JSON 解析失败做了专门处理很多免费接口偶尔会返回一段 HTML 错误页不处理的话报错信息会让人一头雾水。5.3 缓存与限流的实现技巧免费接口的配额是有限的同一个数据反复请求就是白白浪费。我的经验是能缓存就缓存能过期就过期。在 Python 里可以用一个内存缓存来实现最简单的按时间过期import time from functools import lru_cache cache_dict {} def cached_api_call(key, ttl300): def decorator(func): def wrapper(*args, **kwargs): cache_key f{key}:{args}:{kwargs} now time.time() if cache_key in cache_dict: data, expire_at cache_dict[cache_key] if expire_at now: return data result func(*args, **kwargs) cache_dict[cache_key] (result, now ttl) return result return wrapper return decorator cached_api_call(stock, ttl10) def get_stock_price(code): return client.get_json(https://hq.sinajs.cn/list code)题外话是缓存要结合业务来设计失效时间。行情数据缓存 10 秒问题不大天气数据缓存半小时甚至更久都行。缓存的本质是用“可能不是最新”换取“更快、更省配额”你需要在两者之间找到适合业务的平衡点。限流方面如果你要并发调用免费接口最好在本地加一个小队列控制每秒请求数。免费接口对并发很敏感经常你本地开个 for 循环 100 个请求同时出去对方直接 429 拒掉。6. 常见问题与排查技巧实录6.1 高频报错速查表调用免费 API 接口报错是家常便饭。我把高频错误码和排查思路整理成一张表遇到问题对照着查能省很多时间状态码常见原因排查方向401API Key 无效或未授权检查 Key 是否复制完整是否有前导/后置空格403接口无权限或封禁检查是否使用了对应的模型/接口查看平台封禁通知404接口地址错误对照文档核对 URL注意拼接时别带多余空格429超出频率限制降低请求频率检查是否有其他进程在共用同一个 Key500服务端异常等几秒重试如果持续出现可能是接口升级中非 JSON 响应被防火墙拦截或需要特定请求头打印原始响应内容检查 User-Agent、Referer我最常遇到的是 401。排查思路很简单先确认 Key 没复制错再确认平台控制台里这个 Key 对应的服务已经开通。有些平台的免费 Key 还要在网页上手动开通指定接口开通前调用一律 401不是你的代码问题。6.2 那些文档里不会写的隐藏限制很多免费接口的文档写得漂漂亮亮但真正跑起来才发现有一堆文档里没写清楚的坑。分享几个我踩过的第一个QPS 限制可能比文档里写的更严格。有些接口文档说“免费版 QPS 5”实际跑起来 3 个并发就开始报错。原因可能是平台在文档之外又加了一层风控或者你被识别成了高风险的调用 IP。第二个免费 Key 容易被平台风控误伤。比如你用本机服务商的动态 IP 去调用一个没什么知名度的接口平台的风控模型可能认为你在刷接口直接返回验证码页或者干脆 403。遇到这种情况检查请求头里的 User-Agent 和 Referer 是否有必要伪装成浏览器。第三个返回字段变动不受承诺约束。免费接口不像收费商业产品那样有严格的兼容性承诺V1 版本的img_url字段可能在某次升级后变成image。所以在解析返回数据之前先做一个字段存在性判断别直接data[img_url]那会让你的服务很脆。第四个也是最重要的免费接口突然不可用是常态。我之前用过一个很顺手的快递查询接口有一天调着调着突然返回余额不足登录控制台才看到平台调整了免费策略。从那以后我在所有调用第三方免费接口的地方都加了降级方案主接口失败就切备用接口备用接口也失败就返回明确的错误提示给用户而不是让用户看一个 500 页面。6.3 多源切换与降级的落地做法前面反复提到多源切换和降级这里给一个最简实现。你可以在项目配置里维护两个数据源轮询或者按优先级调用失败超过阈值就自动切换。拿查天气举例SOURCES [ {name: qweather, url: https://devapi.qweather.com/v7/weather/now, key: }, {name: openweather, url: https://api.openweathermap.org/data/2.5/weather, key: }, ] def get_weather(city_id): errors [] for source in SOURCES: try: if source[name] qweather: params {location: city_id, key: source[key]} else: params {q: city_id, appid: source[key]} data client.get_json(source[url], paramsparams) if data: return data except Exception as e: errors.append(f{source[name]} 失败: {e}) continue raise RuntimeError(f所有天气源均失败: {errors})这种写法的好处是任何一个数据源挂了系统还能通过另一个源继续工作。做免费接口应用这是最核心的生存法则——免费资源天然不可靠只有拥抱不确定性才能把不可靠变成可控。我在实际测试中还发现一个问题两个数据源返回的数据格式差异很大一个温度用摄氏、一个用开尔文一个时间是时间戳、一个是字符串。切换数据源之后你原本的字段映射逻辑也要跟着变。所以更优雅的做法是在数据源层就统一字段格式转换成自己业务对象之后再往上抛上游永远不用关心你到底调的是哪家服务。最后再分享一个小技巧。很多人收藏接口喜欢直接扔收藏夹结果三个月之后想用发现接口早变了还得重新找。我建议你建一个文本文件或者思维导图按“类目 接口名 文档地址 申请状态 已用额度”来记录每次新用一个接口就补一行每季度检查一次还需要哪些。真到项目里要用了直接打开这个清单比在浏览器收藏夹里翻来翻去高效得多。
