该系统将基于目前比较流行的网络爬虫技术, 对网站上的天气数据进行查询分析, 最终使客户能够通过简单的操作, 快速, 准确的获取目标天气数据。主要包括两部分的功能, 第一部分是天气数据查询, 包括时间段数据查询, 实时天气数据查询;第二部分是打印查询出的天气数据。
实现这个项目时,可以先学习一下cJSON
main.c
#include <stdio.h>
#include <unistd.h>
#include "grab.h"
int main(int argc,const char *argv[])
{
char city[128] = {0};
int choose = 0;
int sockfd = init_cli(); //初始化客户端
while(1)
{
menu(); //打印一个菜单
printf("input need find city:");
scanf("%s",city);
printf("input need find weather:");
scanf("%d",&choose);
switch(choose)
{
case 1:
find_now_weather(sockfd,city); //查找当前天气
recv_weather(sockfd); //接收并打印当前天气
break;
case 2:
find_future_weather(sockfd,citi); //查找未来天气
recv_weather1(sockfd); //接收并打印未来天气
}
}
close(sockfd);
return 0;
}
grab.c:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "cJSON.h"
int init_cli()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
return -1;
}
struct sockaddr_in ser;
ser.sin_family = AF_INET;
ser.sin_port = htons(80);
ser.sin_addr.s_addr = inet_addr("103.205.5.228");
int ret = connect(sockfd,(struct sockaddr *)&ser,sizeof(ser));
if(ret < 0)
{
perror("fail connect:");
return -1;
}
return sockfd;
}
void menu()
{
printf("---------1.查询实时天气----------\n");
printf("---------2.查询未来天气----------\n");
}
void find_now_weather(int sockfd,char *city)
{
char buff[1024] = {0};
memset(buff,0,sizeof(buff));
sprintf(buff,"GET /?app=weather.today&cityNm=%s&appkey=75258&sign=368fe47199076f69e8509979b1d9eeff&format=json HTTP/1.1\r\n""Host: api.k780.com\r\n""User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0\r\n""Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.Z\r\n""Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\r\n""connection: close\r\n\r\n",city);
//请求报文,把要查询的城市拼进去,实现城市天气的查询
ssize_t size = send(sockfd,buff,strlen(buff),0);
if(size < 0)
{
perror("fail send:");
return;
}
return;
}
Void recv_weather(int sockfd)
{
char buff[10240] = {0};
ssize_t size = recv(sockfd,buff,sizeof(buff) - 1,0);
if(size < 1)
{
perror("fail recv:");
return;
}
printf("%s\n",buff);
int i=0; //从这里开始使用cJSON进行解析
while(1) //首先定位到cJSON数据的开头
{
if('{' == buff[i])
{
break;
}
i++;
}
const char *json_string = &buff[i];
cJSON *root = cJSoN_Parse(json_string);
if(!root)
{
printf("fail get root\n");
return;
}
cJSoN *success = cJsoN_GetobjectItem(root,"success");
//先解析未被嵌套的键值对,根结点
cJSON *result = cJsoN_GetobjectItem(root,"result");
printf("success:%s\n",success->valuestring);
if(cJsoN_IsArray(result)) //判断result中有没有数组,如果有使用数组的解析方法
{
i = 0;
for(i = 0;i < soN_GetArraySize(result);++i)
{
cJSON *item = cJSoN_GetArrayItem(result,i); //解析result键值对数组
cJSON *weaid = cJSON_GetobjectItem(item,"weaid");
//根据得到的item解析键值对成员
printf("weaid:%s\n",weaid->valuestring);
}
return;
}
cJSON *weaid = cJsoN_GetobjectItem(result,"weaid");
//再解析嵌套中的键值对,result结点
printf("weaid:%s\n",weaid->valuestring);
cJSON *days = cJSON_GetobjectItem(result,"days");
printf("days:%s\n",days->valuestring);
cJSON *week = cJSON_GetobjectItem(result,"week");
printf("week:%s\n",week->valuestring);
cJSON *citynm = cJsoN_GetobjectItem(result,"citynm");
printf("citynm:%s\n",citynm->valuestring);
return;
}