Bootstrap

基于http协议的天气爬虫

该系统将基于目前比较流行的网络爬虫技术, 对网站上的天气数据进行查询分析, 最终使客户能够通过简单的操作, 快速, 准确的获取目标天气数据。主要包括两部分的功能, 第一部分是天气数据查询, 包括时间段数据查询, 实时天气数据查询;第二部分是打印查询出的天气数据。

实现这个项目时,可以先学习一下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;
}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;