ESP8266HTTPClient库 get请求json数据并解析

本示例使用零知-ESP8266来获取天气信息,首先需要安装库:ArduinoJson-v5.13.5.zip(点击下载)

也可以在GitHub下载,注意要下载5.~版本

一、安装库

解压,安装到库

选择解压文件,安装

也可以解压直接复制到E:\lingzhi_library\lingzhi-build\libraries(你lingzhi_library存放的位置)这样就完成安装了

二、代码

1、打开零知开源开发工具


							

/**
* Demo:
*    演示Http请求天气接口信息
* @date 2019/06/01
*/
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>

//以下三个定义为调试定义
const char* AP_SSID     = "zaixinjian2019";         //  **********-- 使用时请修改为当前你的 wifi ssid
const char* AP_PSK = "2019zaixinjiancp";         //  **********-- 使用时请修改为当前你的 wifi 密码
const char* HOST = "http://api.seniverse.com";
const char* APIKEY = "wcmquevztdy1jpca";        //API KEY
const char* CITY = "shenzhen";
const char* LANGUAGE = "zh-Hans";//zh-Hans 简体中文  会显示乱码

// 我们要从此网页中提取的数据的类型
struct WeatherData {
	char city[16];//城市名称
	char weather[32];//天气介绍(多云...)
	char temp[16];//温度
	char udate[32];//更新时间
};

HTTPClient http;
//get请求url
String GetUrl="http://api.seniverse.com/v3/weather/now.json"
"?key=wcmquevztdy1jpca&location=shenzhen&language=zh-Hans";
String response;
WeatherData weatherData;//结构体实例化

void setup() {
	// put your setup code here, to run once:
	WiFi.mode(WIFI_STA);     //设置esp8266 工作模式:客户端模式
	Serial.begin(115200);
	Serial.print("Connecting to ");
	Serial.println(AP_SSID);
	WiFi.begin(AP_SSID, AP_PSK);   //连接wifi
	WiFi.setAutoConnect(true);
	while (WiFi.status() != WL_CONNECTED) {
		//这个函数是wifi连接状态,返回wifi链接状态
		delay(500);
		Serial.print(".");
	}
	Serial.println("");
	Serial.println("WiFi connected");
	Serial.println("IP address: " + WiFi.localIP());
	
	
	//设置超时
	http.setTimeout(5000);
	//设置请求url
	http.begin(GetUrl);
	//以下为设置一些头  其实没什么用 最重要是后端服务器支持
	http.setUserAgent("esp8266");//用户代理版本
	http.setAuthorization("esp8266","yssy");//用户校验信息
}

void loop() {
	//心知天气  发送http  get请求
	int httpCode = http.GET();
	if (httpCode > 0) {
		Serial.printf("[HTTP] GET... code: %d\n", httpCode);
		//判断请求是否成功
		if (httpCode == HTTP_CODE_OK) {
			//读取响应内容
			response = http.getString();
			Serial.println("Get the data from Internet!");
			Serial.println(response);
			//解析响应内容
			if (parseUserData(response, &weatherData)) {
				//打印响应内容
				printUserData(&weatherData);
			}
		}
	} else {
		Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
	}
	http.end();
	delay(10000);//每10s调用一次
}

/**
* @Desc 解析数据 Json解析
* 数据格式如下:
* {
	*    "results": [
	*        {
		*            "location": {
			*                "id": "WX4FBXXFKE4F",
			*                "name": "北京",
			*                "country": "CN",
			*                "path": "北京,北京,中国",
			*                "timezone": "Asia/Shanghai",
			*                "timezone_offset": "+08:00"
		*            },
		*            "now": {
			*                "text": "多云",
			*                "code": "4",
			*                "temperature": "23"
		*            },
		*            "last_update": "2017-09-13T09:51:00+08:00"
	*        }
	*    ]
*}
*/
bool parseUserData(String content, struct WeatherData* weatherData) {
	//    -- 根据我们需要解析的数据来计算JSON缓冲区最佳大小
	//   如果你使用StaticJsonBuffer时才需要
	//    const size_t BUFFER_SIZE = 1024;
	//   在堆栈上分配一个临时内存池
	//    StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
	//    -- 如果堆栈的内存池太大,使用 DynamicJsonBuffer jsonBuffer 代替
	DynamicJsonBuffer jsonBuffer;
	
	JsonObject& root = jsonBuffer.parseObject(content);
	
	if (!root.success()) {
		Serial.println("JSON parsing failed!");
		return false;
	}
	
	//复制我们感兴趣的字符串
	strcpy(weatherData->city, root["results"][0]["location"]["name"]);
	strcpy(weatherData->weather, root["results"][0]["now"]["text"]);
	strcpy(weatherData->temp, root["results"][0]["now"]["temperature"]);
	strcpy(weatherData->udate, root["results"][0]["last_update"]);
	//  -- 这不是强制复制,你可以使用指针,因为他们是指向“内容”缓冲区内,所以你需要确保
	//   当你读取字符串时它仍在内存中
	return true;
}

// 打印从JSON中提取的数据
void printUserData(const struct WeatherData* weatherData) {
	Serial.println("Print parsed data :");
	Serial.print("City : ");
	Serial.print(weatherData->city);
	Serial.print(", \t");
	Serial.print("Weather : ");
	Serial.print(weatherData->weather);
	Serial.print(",\t");
	Serial.print("Temp : ");
	Serial.print(weatherData->temp);
	Serial.print(" C");
	Serial.print(",\t");
	Serial.print("Last Updata : ");
	Serial.print(weatherData->udate);
	Serial.println("\r\n");
}
				
				

2、验证代码,上传程序,打开调试 结果如下