HTTP 客户端获取天气 API
📅 2026-05-07 · 📂 硬件编程 · ⏱ 阅读约 6 分钟
概述
连上 WiFi 之后干什么?当然是上网拿数据!本篇教你用 ESP32 作为 HTTP 客户端,请求互联网 API,获取实时天气数据并解析 JSON。这是 IoT 数据采集的核心技能。
学习目标:掌握 HTTP GET/POST 请求,理解 JSON 解析,学会使用 ArduinoJson 库。
物料清单
- ESP32 开发板 ×1
- WiFi 网络
- 免费天气 API Key(和风天气 / OpenWeatherMap)
无额外硬件。注册和风天气免费开发者账号获取 API Key(每天 1000 次免费调用)。
HTTP 基础
| 方法 | 用途 | 示例 |
|---|
| GET | 获取数据 | 请求天气信息 |
| POST | 提交数据 | 上报传感器数据 |
| PUT/PATCH | 更新数据 | 修改设备配置 |
实战:获取和风天气实时数据
// HTTP_Weather.ino — 获取实时天气
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "WiFi名";
const char* password = "WiFi密码";
// 和风天气 API(替换为你的 Key)
const char* apiKey = "你的KEY";
const char* cityId = "101010100"; // 北京
void getWeather() {
HTTPClient http;
String url = String("https://devapi.qweather.com/v7/weather/now?location=") + cityId + "&key=" + apiKey;
http.begin(url);
int code = http.GET();
if (code == 200) {
String payload = http.getString();
Serial.println("✓ 获取成功");
JsonDocument doc;
deserializeJson(doc, payload);
const char* weather = doc["now"]["text"];
const char* temp = doc["now"]["temp"];
const char* humidity = doc["now"]["humidity"];
Serial.printf("天气:%s 温度:%s°C 湿度:%s%%
", weather, temp, humidity);
} else {
Serial.printf("请求失败 HTTP %d
", code);
}
http.end();
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println("WiFi已连接");
}
void loop() {
getWeather();
delay(600000); // 10分钟更新一次
}
HTTPS 证书问题
⚠️ HTTPS 证书:和风天气 API 使用 HTTPS。ESP32 默认不验证证书(不安全但方便)。如需验证,调用 client.setCACert(rootCA) 加载根证书。
如果 HTTPS 连接失败,检查:1) ESP32 系统时间是否正确(证书有效期校验);2) 堆内存是否足够(ArduinoJson 解析大 JSON 容易 OOM)。
JSON 解析最佳实践
// ArduinoJson v7 内存优化
#include <ArduinoJson.h>
// 使用 StaticJsonDocument 避免堆碎片
StaticJsonDocument<1024> doc;
// 或使用 JsonDocument + 预估大小
// JsonDocument doc;
// deserializeJson(doc, payload, DeserializationOption::NestingLimit(5));
void parseCompact(String& json) {
auto error = deserializeJson(doc, json);
if (error) {
Serial.printf("JSON解析失败: %s
", error.c_str());
return;
}
// 安全访问: doc["key"] | "default"
const char* val = doc["now"]["text"] | "未知";
}
常见问题
⚠️ 内存不足:ArduinoJson v6/v7 的 DynamicJsonDocument 会动态分配堆内存。ESP32 默认堆只有 ~280KB。对复杂 JSON 用 Streaming 解析或增大 partition。
⚠️ API 限流:免费 API 有 QPS 限制。高频采集需加缓存+间隔控制,避免被封。
💡 超时设置:http.setTimeout(10000) 设置 10 秒超时,避免网络不稳时卡死。