项目:基于网络爬虫技术的天气预报数据查询

一、获取天气接口

            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

七、运行结果

①make编译/更新

②输入查询天气

③输入所查询数字

④查询该城市当前天气

⑤查询该城市未来天气

⑥退出

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值