说明
- 有不少网络API是通过http get或者post方式进行请求的,
 - 实际上这些api的请求往往都是相对固定的格式,而http是建立在tcp上的,我们往往只需要在TCP client的基础上,进行简单的模拟 即可实现这些API的访问
 - 本文以高德的天气API,基于ch32v208的tcp client例程,来实现实时天气的获取
 
实现
先获取api请求所用到的key
这里按照其网页文档来就行
模拟请求
用浏览器,或者curl之类的工具模拟请求我们的API:
下面我们用curl模拟请求合肥的实时天气
$ curl http://restapi.amap.com/v3/weather/weatherInfo\?city\=340100\&key\=<你申请的apikey>
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   255  100   255    0     0   1782      0 --:--:-- --:--:-- --:--:--  1795{"status":"1","count":"1","info":"OK","infocode":"10000","lives":[{"province":"安徽","city":"合肥市","adcode":"340100",
"weather":"晴","temperature":"8","winddirection":"东南","windpower":"≤3","humidity":"41","reporttime":"2022-12-30 13:04:50"}]}
对请求进行抓包分析
由于请求比较简单,我们简单的抓下http请求的数据,然后用芯片去模拟就行
构造tcp请求数据包
#define API_DOMAIN  "restapi.amap.com"                  /*DNS请求的API的域名*/
#define API_CITY    "340100"                            /*安徽合肥*/
#define API_KEY     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  /*申请到的APIkey*/
const char header[] = \
            "GET /v3/weather/weatherInfo?city=%s&key=%s HTTP/1.1\r\n" \
            "Host: %s\r\n"\
            "User-Agent: curl/7.85.0\r\n"\
            "Accept: */*\r\n"\
            "\r\n";
char message[1024];
sprintf(message,header,API_CITY,API_KEY ,API_DOMAIN);
uint32_t send_len
send_len = strlen(message);
tcp建立后,进行请求
i = WCHNET_SocketSend(SocketId,message,&send_len);
tcp收到数据进行解析
这里我们拿到的是json数据,我们通过strstr比较简单的获取json的起始地址(判断收到的数据第一次出现{" 的位置)
    char *json_start = strstr((char *)SocketInf[id].RecvReadPoint,"{\"");
    if(json_start == NULL) {
        WCHNET_SocketRecv(id, NULL, &len);
        return ;
    }
然后使用cJSON 进行解析即可,注意cJSON的free和delete
    cJSON *arrayItem = cJSON_GetObjectItem(root,"status");
    out = cJSON_Print(arrayItem);
    //PRINT("%s\n",out);
    cJSON_free(out);
    arrayItem = cJSON_GetObjectItem(root,"info");
    out = cJSON_Print(arrayItem);
    //PRINT("%s\n",out);
    cJSON_free(out);
    arrayItem = cJSON_GetObjectItem(root,"infocode");
    out = cJSON_Print(arrayItem);
    PRINT("%s\n",out);
    cJSON_free(out);
    arrayItem = cJSON_GetObjectItem(root,"lives");
    out = cJSON_Print(arrayItem);
    PRINT("%s\n",out);
    cJSON_free(out);
    arrayItem = cJSON_GetArrayItem(arrayItem,0);
    out = cJSON_Print(arrayItem);
    PRINT("%s\n",out);
    cJSON_free(out);
    cJSON *item;
    item = cJSON_GetObjectItem(arrayItem,"province");
    out = cJSON_Print(item);
    PRINT("province:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"city");
    out = cJSON_Print(item);
    PRINT("city:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"adcode");
    out = cJSON_Print(item);
    PRINT("adcode:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"weather");
    out = cJSON_Print(item);
    PRINT("weather:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"temperature");
    out = cJSON_Print(item);
    PRINT("temperature:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"winddirection");
    out = cJSON_Print(item);
    PRINT("winddirection:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"windpower");
    out = cJSON_Print(item);
    PRINT("windpower:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"humidity");
    out = cJSON_Print(item);
    PRINT("humidity:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"reporttime");
    out = cJSON_Print(item);
    PRINT("reporttime:%s\n",out);
    cJSON_free(out);
    cJSON_Delete(root);
最终的结果
"10000"
[{
		"province":	"安徽",
		"city":	"���肥市",
		"adcode":	"340100",
		"weather":	"晴",
		"temperature":	"8",
		"winddirection":	"东南",
		"windpower":	"≤3",
		"humidity":	"40",
		"reporttime":	"2022-12-30 13:31:36"
	}]
{
	"province":	"安徽",
	"city":	"合肥市",
	"adcode":	"340100",
	"weather":	"晴",
	"temperature":	"8",
	"winddirection":	"东南",
	"windpower":	"≤3",
	"humidity":	"40",
	"reporttime":	"2022-12-30 13:31:36"
}
province:"安徽"
city:"合肥市"
adcode:"340100"
weather:"晴"
temperature:"8"
winddirection:"东南"
windpower:"≤3"
humidity:"40"
reporttime:"2022-12-30 13:31:36"
TCP Disconnect
附件
工程放到,ch32v20x evt>EXAM\ETH 下
把自己申请的apikey 替换掉
#define API_KEY     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  /*申请到的APIkey*/
串口打印在PA9,115200
https://gitee.com/iot-fan/iot-fan_at_cnblogs/tree/master/CH32V208/AN/ch32v208_http_get_amap_weather_api_test

                
            
        
浙公网安备 33010602011771号