一、获取天气接口
1.注册nowapi用户
2.开通天气预报服务接口
3.填写个人信息
4.点击数据接口
5.点击天气预报
6.点击立即开通
7.点击免费试用套餐
8.点击确认订单
9.获得生成的Appkey和Sign标识
注意:图片是我的AppKey(已不能使用),申请免费的后,找到自己的AppKey
点击全部接口——>点击天气接口——>实时天气
将图片中appkey=10003改成appkey=68413(按照自己申请的改),sign一样改成自己的。
二、wireshark抓取报文/分析报文
抓取报文之前明白
HTTP交互的过程
1.建立TCP连接2.发送HTTP请求报文3.回复HTTP响应报文4.断开TCP连接
CJSON的使用方法
cJSON_Parse
从给定的json字符串中得到cjson对象
cJSON_GetObjectItem
根据键获取对应的值(cjson对象)
cJSON_Delete
删除cjson对象,释放链表占用的内存空间
cJSON_GetArraySize
获取cjson对象数组成员的个数
cJSON_GetArrayItem
根据下标获取cjosn对象数组中的对象
三、流程图设计
四、weather.c
切记:后面接收到对方发来的报文(使用printf可以看到)一定要进行分析从而截取自己所需要的部分
#include "head.h"
#include "cJSON.h"//cJIOSN
int init_tcp_cli(char *ip,unsigned short port)//TCP的通信
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(-1 == sockfd )
{
perror("fail sockfd");
return -1;
}
struct sockaddr_in ser;
ser.sin_family = AF_INET;
ser.sin_port = htons(port);
ser.sin_addr.s_addr = inet_addr(ip);
int ret = connect(sockfd,(struct sockaddr *)&ser,sizeof(ser));
if(-1 == ret)
{
perror("fail connect");
return -1;
}
return sockfd;
}
int send_http_request(int sockfd,char *purl)//传递HTTP报文的头
{
char tmpbuff[4096] = {0};
ssize_t nsize = 0;
sprintf(tmpbuff, "GET %s HTTP/1.1\r\n", purl);//%s是搜索的城市purl
sprintf(tmpbuff, "%sHost: api.k780.com\r\n", tmpbuff);
sprintf(tmpbuff, "%sUser-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0\r\n", tmpbuff);
sprintf(tmpbuff, "%sAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n", tmpbuff);
sprintf(tmpbuff, "%sAccept-Language: en-US,en;q=0.5\r\n", tmpbuff);
sprintf(tmpbuff, "%sAccept-Encoding: gzip, deflate\r\n", tmpbuff);
sprintf(tmpbuff, "%sConnection: keep-alive\r\n\r\n", tmpbuff);
//可以自己wires hark抓取报文 拼接以上的信息
nsize = send(sockfd, tmpbuff, strlen(tmpbuff), 0);//发送报文
if (-1 == nsize)
{
perror("fail to send");
return -1;
}
return 0 ;
}
int recv_http_response(int sockfd, char *ptmpbuff, int maxlen )
{
ssize_t nsize = 0;
nsize = recv(sockfd, ptmpbuff, maxlen, 0);//接收对面发来的内容
if (-1 == nsize)
{
perror("fail to recv");
return -1;
}
}
int main(int argc, char const *argv[])
{
char city[1024] = {0};
int tmp ;
int sockfd = 0;
char buff[1024] = {0};
char tempbuff[4096] = {0};
printf("--------天气预报查询--------\n");
printf("输入所要查询的城市:");
scanf("%s",city);
getchar();
printf("输入1:查询该城市当前天气\n");
printf("输入2:查询该城市未来天气\n");
printf("输入3:查询该城市历史天气\n");
printf("输入4:退出\n");
while(1)
{
scanf("%d",&tmp);
if( 1 == tmp)
{
sockfd = init_tcp_cli("103.205.5.249",80);
sprintf(buff,"/?app=weather.today&weaid=%s&appkey=68413&sign=ab1a2870f6ef872c615d16c6c95611d6&format=json",city);
send_http_request(sockfd,buff);//发送自己所要信息的报文
recv_http_response(sockfd,tempbuff,sizeof(tempbuff));//接收对方发来的报文
//printf("%s\n",tempbuff),输出接收到对方发来的报文从而进行分析
char *p = NULL;
p = strstr(tempbuff,"result");//分析截取对方发送的报文,截取自己所需要的信息段
p = strstr(p,"{");
p = strtok(p,"}");
p = strcat(p,"}");//截取后面的关键信息,学习cJSONd如何使用
cJSON *json = NULL;
cJSON *q = NULL;
json = cJSON_Parse(p);//从给定的json字符串中得到cjson对象
q = cJSON_GetObjectItem(json, "weaid");//根据键获取对应的值(cjson对象)
printf("weaid:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "days");
printf("days:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "week");
printf("week:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "cityno");
printf("cityno:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "citynm");
printf("citynm:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "cityid");
printf("cityid:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "temperature");
printf("temperature:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "temperature_curr");
printf("temperature_curr:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "humidity");
printf("humidity:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "aqi");
printf("aqi:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "weather");
printf("weather:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "weather_curr");
printf("weather_curr:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "weather_icon");
printf("weather_icon:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "weather_icon1");
printf("weather_icon1:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "wind");
printf("wind:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "winp");
printf("winp:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "temp_high");
printf("temp_high:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "temp_low");
printf("temp_low:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "temp_curr");
printf("temp_curr:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "humi_high");
printf("humi_high:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "weatid");
printf("weatid:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "weatid1");
printf("weatid1:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "windid");
printf("windid:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "winpid");
printf("winpid:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(json, "weather_iconid");
printf("weather_iconid:%s\n", q ->valuestring);
close(sockfd);
cJSON_Delete(json);
}
else if(2 == tmp)
{
sockfd = init_tcp_cli("103.205.5.249",80);
sprintf(buff,"/?app=weather.future&weaid=%s&&appkey=68413&sign=ab1a2870f6ef872c615d16c6c95611d6&format=json ",city);
send_http_request(sockfd,buff);
recv_http_response(sockfd,tempbuff,sizeof(tempbuff));
char *e = NULL;
e = strstr(tempbuff,"[");
e = strtok(e,"]");
e = strcat(e,"]");
int CurLen = 0;
int i = 0;
cJSON *json = NULL;
cJSON *q = NULL;
cJSON *pItem = NULL;
json = cJSON_Parse(e);
CurLen = cJSON_GetArraySize(json);//获取数组大小
for (i = 0; i < CurLen; i++)
{
pItem = cJSON_GetArrayItem(json, i);//从json里面找到第i{}组,使用pItem接收第i组,获取数组元素g
if (NULL == pItem)
{
fprintf(stderr, "获得数组元素失败!\n");
return -1;
}
q = cJSON_GetObjectItem(pItem, "weaid");//根据键获取对应的值(cjson对象)
printf("weaid:%s\n", q->valuestring);
q = cJSON_GetObjectItem(pItem, "days");
printf("days:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "week");
printf("week:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "cityno");
printf("cityno:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "citynm");
printf("citynm:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "cityid");
printf("cityid:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "temperature");
printf("temperature:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "humidity");
printf("humidity:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "weather");
printf("weather:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "weather_icon");
printf("weather_icon:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "weather_icon1");
printf("weather_icon1:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "wind");
printf("wind:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "winp");
printf("winp:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "temp_high");
printf("temp_high:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "temp_low");
printf("temp_low:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "humi_high");
printf("humi_high:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "humi_low");
printf("humi_low:%s\n", q ->valuestring) ;
q = cJSON_GetObjectItem(pItem, "weatid");
printf("weatid:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "weatid1");
printf("weatid1:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "windid");
printf("windid:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "winpid");
printf("winpid:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "weather_iconid");
printf("weather_iconid:%s\n", q ->valuestring);
q = cJSON_GetObjectItem(pItem, "weather_iconid1");
printf("weather_iconid1:%s\n", q ->valuestring);
printf("=======================================\n");
}
close(sockfd);
cJSON_Delete(json);
}
else if(3 == tmp)
{
printf("购买后查询历史天气\n");
}
else if(4 == tmp)
{
break;
}
}
return 0;
}
五、Makefile(切记添加cJSON.c)
OBJ:=day //运行时./day
OBJS+=weather.c
OBJS+=cJSON.c$(OBJ) : $(OBJS)
gcc $^ -o $@
.PHONY:
clean:
rm $(OBJ)
六、头文件
#ifndef __HEAD_H__
#define __HEAD_H__#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <poll.h>
#include <pthread.h>#endif