一、项目背景以及项目意义

项目背景:

爬虫技术的核心目的是自动化地从互联网上采集,提取和存储数据。网络爬虫是一种自动化程序,用于从互联网上抓取数据并进行处理。C语言因其高效性和接近硬件的特性,常被用于开发高性能的网络爬虫,尤其是在资源受限或需要极致性能的场景中。

项目意义:

综合使用了学习到的网络的TCP协议,套接字编程和http协议,与网络服务端建立相关的联系,从网络网址当中爬取自己想要的相关数据。

二、项目实现的功能

1.通过TCP协议建立联系

2.通过http协议获得响应报文以及正文

3.解析HTML和相应网页内容

4.提取自己想要的数据

三、项目的整体框图以及各部分如何实现

四、项目中的流程图及说明

五、项目中遇到的问题及解决方法

1.在查询https://sapi.k780.com/的端口和IP地址时只找到https协议的地址造成无法爬取

解决方法:通过在网上搜集资料了解应该将网址上的s和sapi的s去掉,即可访问http网址

2.在将请求报文发送时,不能将所想要查询的城市输入到请求报文当中

解决方法:通过主函数传参以及利用了snprintf函数将请求报文保存到了一个数组当中

3.在将回复的响应报文保存到文本当中后,不知道怎么将文本当中的数据读到cjson当中

解决方法:利用了一个strstr函数对文本当中的数据进行了一个定位,将指针定位到了{\处进行解析报文

4.在解析cjson报文当中不知道如何解析嵌套的JSON数据

解决方法:通过第一次先解析到外层的JSON数据,然后再依次往里面进行解析,其相应报文中的数字,汉语,字母等都是字符串类型的要用valuestring。

5.在JSON数组当中解析JSON数据

解决方法:在一个JSON数组当中转换字符串应该先获得该数组的大小,然后进行循环,利用item进行获取数组,再获取数组当中想要的数据

#include "pachong.h"
#include "cJSON.h"int main(int argc,const char *argv[])
{if(argc != 2){printf("Usage : ./a.out <城市名字>\n");return -1;}int sockfd = create_tcp_connect();if(sockfd < 0){perror("socket error");return -1;}printf("-----------------------------\n");printf("查询实时天气或天气预报-------\n");printf("1.查询实时天气---------------\n");printf("2.查询天气预报---------------\n");printf("3.退出-----------------------\n");printf("-----------------------------\n");int choose;scanf("%d",&choose);switch (choose){case 1: send_http_request_weather_today(sockfd,argv[1]);recv_http_response(sockfd);find_today_weather();break;case 2: send_http_requesr_weather_prediction(sockfd,argv[1]);recv_http_response(sockfd);find_prediction_weather();break;case 3: exit_program(sockfd);break;default:break;}close(sockfd);return 0;
}
#include "pachong.h"
#include "cJSON.h"
#define SER_PORT 80
#define SER_IP "8.129.233.227"
int create_tcp_connect()
{int sockfd = socket(AF_INET,SOCK_STREAM,0);if(sockfd < 0){perror("socket error");return -1;}struct  sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(SER_PORT);seraddr.sin_addr.s_addr = inet_addr(SER_IP); int ret = connect(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr));if(ret < 0){perror("connect error");return -1;}return sockfd;}
int send_http_request_weather_today(int sockfd,const char *cityname)
{char buff[4096] = {0};snprintf(buff,sizeof(buff),"GET /?app=weather.today&cityNm=%s&appkey=77275&sign=3b1921902ede0a45608c50b0f1b919c3&format=json HTTP/1.1\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.7\r\n""Accept-Encoding: gzip, deflate\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""Cache-Control: max-age=0\r\n""Connection: close\r\n""Host: api.k780.com\r\n""Upgrade-Insecure-Requests: 1\r\n""User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0 \r\n""\r\n",cityname);ssize_t cnt = send(sockfd,buff,strlen(buff),0);if(cnt < 0){perror("send error");return -1;}return 0;}
void exit_program(int sockfd)
{if(sockfd >= 0){close(sockfd);}printf("已退出\n");exit(0);}int send_http_requesr_weather_prediction(int sockfd,const char *cityname)
{ char buff[4096] = {0};snprintf(buff,sizeof(buff),"GET /?app=weather.future&cityNm=%s&appkey=77275&sign=3b1921902ede0a45608c50b0f1b919c3&format=json HTTP/1.1\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.7\r\n""Accept-Encoding: gzip, deflate\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""Cache-Control: max-age=0\r\n""Connection: close\r\n""Host: api.k780.com\r\n""Upgrade-Insecure-Requests: 1\r\n""User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0\r\n""\r\n",cityname);// printf("buff:%s\n",buff);ssize_t cnt = send(sockfd,buff,strlen(buff),0);if(cnt < 0){perror("send error");return -1;}return 0;}
int recv_http_response(int sockfd)
{char buff[1024] = {0};int fd = open("./1.txt",O_WRONLY | O_CREAT |O_TRUNC,0664);if(fd < 0){perror("open error");return -1;}while(1){ssize_t cnt = recv(sockfd,buff,sizeof(buff),0);if(cnt < 0){perror("recv error");return -1;}else if(0 == cnt){printf("off\n");break;}write(fd,buff,cnt);// write(1,buff,cnt);}close(fd);return 0;}
int find_today_weather()
{int fd = open("1.txt",O_RDONLY);if(fd < 0){perror("open error");return -1;}char buff[40960] = {0};ssize_t cnt = read(fd,buff,sizeof(buff) - 1);if(cnt <= 0){perror("read error");return -1;}close(fd);buff[cnt] = '\0';const char *json_start = strstr(buff,"\r\n\r\n");json_start = strstr(buff,"{\"");cJSON* json = NULL;json = cJSON_Parse(json_start);if(!json){   printf("json error : %s",cJSON_GetErrorPtr());return -1;}else{cJSON* json_result = cJSON_GetObjectItem(json,"result");cJSON* json_days = cJSON_GetObjectItem(json_result,"days");if(cJSON_IsString(json_days)){printf("日期:%s\n",json_days->valuestring);}cJSON* json_citynm = cJSON_GetObjectItem(json_result,"citynm");if(cJSON_IsString(json_citynm)){printf("城市:%s\n",json_citynm->valuestring);}cJSON* json_week = cJSON_GetObjectItem(json_result,"week");if(cJSON_IsString(json_week)){printf("星期:%s\n",json_week->valuestring);}cJSON* json_temperature = cJSON_GetObjectItem(json_result,"temperature");if(cJSON_IsString(json_temperature)){printf("最高温度/最低温度:%s\n",json_temperature->valuestring);}cJSON* json_temperature_curr = cJSON_GetObjectItem(json_result,"temperature_curr");if(cJSON_IsString(json_temperature_curr)){printf("当前温度:%s\n",json_temperature_curr->valuestring);}cJSON* json_humidity = cJSON_GetObjectItem(json_result,"humidity");if(cJSON_IsString(json_humidity)){printf("湿度:%s\n",json_humidity->valuestring);}cJSON* json_weather = cJSON_GetObjectItem(json_result,"weather");if(cJSON_IsString(json_weather)){printf("今天天气:%s\n",json_weather->valuestring);}cJSON* json_weather_curr = cJSON_GetObjectItem(json_result,"weather_curr");if(cJSON_IsString(json_weather_curr)){printf("当前天气:%s\n",json_weather_curr->valuestring);}cJSON* json_wind = cJSON_GetObjectItem(json_result,"wind");if(cJSON_IsString(json_wind)){printf("风向:%s\n",json_wind->valuestring);}   cJSON* json_winp = cJSON_GetObjectItem(json_result,"winp");if(cJSON_IsString(json_winp)){printf("风力:%s\n",json_winp->valuestring);}   }cJSON_Delete(json);return 0;}
int find_prediction_weather()
{int fd = open("1.txt",O_RDONLY);if(fd < 0){perror("open error");return -1;}char buff[40960] = {0};ssize_t cnt = read(fd,buff,sizeof(buff) - 1);if(cnt <= 0){perror("read error");return -1;}close(fd);buff[cnt] = '\0';const char *json_start = strstr(buff,"\r\n\r\n");json_start = strstr(buff,"{\"");cJSON* json = NULL;json = cJSON_Parse(json_start);if(!json){   printf("json error : %s",cJSON_GetErrorPtr());return -1;}else{cJSON* json_result = cJSON_GetObjectItem(json,"result");if(!json_result){printf("json_result error : %s",cJSON_GetErrorPtr());return -1;}int size = cJSON_GetArraySize(json_result);for(int i = 0;i < size;i++){cJSON* item = cJSON_GetArrayItem(json_result,i);if(!item){printf("item error : %s",cJSON_GetErrorPtr());return -1;}if(cJSON_IsObject(item)){cJSON* json_days = cJSON_GetObjectItem(item,"days");if(cJSON_IsString(json_days)){printf("日期:%s\n",json_days->valuestring);}else{printf("error\n");}cJSON* json_citynm = cJSON_GetObjectItem(item,"citynm");if(cJSON_IsString(json_citynm)){printf("城市:%s\n",json_citynm->valuestring);}cJSON* json_week = cJSON_GetObjectItem(item,"week");if(cJSON_IsString(json_week)){printf("星期:%s\n",json_week->valuestring);}cJSON* json_temperature = cJSON_GetObjectItem(item,"temperature");if(cJSON_IsString(json_temperature)){printf("最高温度/最低温度:%s\n",json_temperature->valuestring);}cJSON* json_temperature_curr = cJSON_GetObjectItem(item,"temperature_curr");if(cJSON_IsString(json_temperature_curr)){printf("当前温度:%s\n",json_temperature_curr->valuestring);}cJSON* json_humidity = cJSON_GetObjectItem(item,"humidity");if(cJSON_IsString(json_humidity)){printf("湿度:%s\n",json_humidity->valuestring);}cJSON* json_weather = cJSON_GetObjectItem(item,"weather");if(cJSON_IsString(json_weather)){printf("今天天气:%s\n",json_weather->valuestring);}cJSON* json_weather_curr = cJSON_GetObjectItem(item,"weather_curr");if(cJSON_IsString(json_weather_curr)){printf("当前天气:%s\n",json_weather_curr->valuestring);}cJSON* json_wind = cJSON_GetObjectItem(item,"wind");if(cJSON_IsString(json_wind)){printf("风向:%s\n",json_wind->valuestring);}   cJSON* json_winp = cJSON_GetObjectItem(item,"winp");if(cJSON_IsString(json_winp)){printf("风力:%s\n",json_winp->valuestring);}printf("\n");}   }}return 0;
}
#ifndef __PACHONG_H__
#define __PACHONG_H__#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> 
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
extern int find_today_weather();
extern void exit_program(int sockfd);
extern int send_http_requesr_weather_prediction(int sockfd,const char *cityname);
extern int send_http_request_weather_today(int sockfd,const char *cityname);
extern int recv_http_response(int sockfd);
extern int create_tcp_connect();
extern int find_prediction_weather();
#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/94528.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/94528.shtml
英文地址,请注明出处:http://en.pswp.cn/web/94528.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 操作 PPT 文件:从新手到高手的实战指南

在日常工作和学习中&#xff0c;PPT 是我们展示信息和进行演示的重要工具。无论是制作报告、演讲还是教学课件&#xff0c;PPT 都扮演着不可或缺的角色。然而&#xff0c;当面对大量重复性的 PPT 编辑任务时&#xff0c;手动操作不仅耗时耗力&#xff0c;还容易出错。幸运的是&…

系统设计中的幂等性

1. 基本概念 幂等性&#xff08;Idempotence&#xff09;是系统设计中经常提到的概念。如果某个操作执行一次或多次都能产生相同的结果&#xff0c;那么它就是幂等的。2. 代码示例 下面这段代码是幂等的。无论你调用多少次&#xff0c;show_my_button 的最终状态都是False。 de…

Pandas vs Polars Excel 数据加载对比报告

📊 Pandas vs Polars Excel 数据加载对比报告 1. 数据基本情况 数据文件:data.xlsx 数据规模:23,670 行 3 列 字段: case_time:日期/时间 case_name:公司名称(字符串) board:所属板块(字符串) 2. 加载方式与代码 Pandas import pandas as pdfrom tools import…

Kafka 为什么具有高吞吐量的特性?

Kafka 高吞吐量原因&#xff1a;面试题总结 在面试中&#xff0c;Kafka 的高吞吐量设计是高频考点&#xff0c;核心需围绕“架构设计”“存储优化”“网络效率”“资源利用”四个维度展开&#xff0c;以下是结构化总结&#xff1a; 一、核心架构&#xff1a;并行化与分层设计分…

MCP 协议原理与系统架构详解—从 Server 配置到 Client 应用

1. MCP MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是开发 Claude 模型的(Anthropic)公司推出的一个开放标准协议&#xff0c;就像是一个 “通用插头” 或者 “USB 接口”&#xff0c;制定了统一的规范&#xff0c;不管是连接数据库、第三方…

uniapp安卓真机调试问题解决总结

uniapp安卓真机调试遇到各种连接不上问题&#xff1a; 手机上打开调试数据线不行&#xff0c;换数据线电脑重启手机重启拔出数据线&#xff0c;换个USB插口。

Linux Qt创建和调用so库的详细教程

一、创建so库1.文件-->新建文件或项目-->Library->C Library&#xff0c;如下图2.工程命名为Example3.一直下一步就可以4、工程创建完成&#xff0c;如下图5、删除Example_global.h6、配置.pro文件# 设置输出目录 DESTDIR $$PWD/output #只生成.so文件 CONFIG plugi…

【深度学习】蒙特卡罗方法:原理、应用与未来趋势

作者选择了由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 三位大佬撰写的《Deep Learning》(人工智能领域的经典教程&#xff0c;深度学习领域研究生必读教材),开始深度学习领域学习&#xff0c;深入全面的理解深度学习的理论知识。 之前的文章参考下面的链接&#xf…

区块链技术原理(18)-以太坊共识机制

文章目录前言什么是共识&#xff1f;什么是共识机制&#xff1f;共识机制的核心目标共识机制的类型PoW&#xff08;工作量证明&#xff09;协议&#xff1a;&#xff08;2015-2022&#xff09;PoS&#xff08;权益证明&#xff09;协议&#xff1a;&#xff08;PoS&#xff0c;…

java基础(十五)计算机网络

网络模型概述 为了使得多种设备能通过网络相互通信&#xff0c;并解决各种不同设备在网络互联中的兼容性问题&#xff0c;国际标准化组织&#xff08;ISO&#xff09;制定了开放式系统互联通信参考模型&#xff08;OSI模型&#xff09;。与此同时&#xff0c;TCP/IP模型作为实际…

idea将服务封装为一个jar包

你使用的是 IntelliJ IDEA 2018&#xff0c;这个版本虽然不是最新的&#xff0c;但完全支持通过 图形化界面 打 JAR 包&#xff08;无需命令行&#xff09;&#xff0c;非常适合你在公司内部将 Snowflake 模块打包成通用组件。下面我将 手把手、一步一步、图文流程式地教你&…

ZYNQ [Petalinux的运行]

一、下载ubuntu 下载地址很多&#xff0c;这里提供了一个&#xff1a;http://mirrors.aliyun.com/ubuntu-releases/14.04/ 推荐开始浏览器下载之后复制下载链接使用迅雷下载。 二、虚拟机安装Ubuntu vmware中安装Ubutun–这部分不展示 安装ssh sudo apt install openssh-s…

excel 破解工作表密码

破解Excel工作表密码可通过易用宝工具、VBA脚本或修改文件格式实现&#xff0c;具体方法需根据文件类型和密码保护类型选择。 ‌使用易用宝工具&#xff08;推荐&#xff09;‌ 适用于Excel 2007及以上版本&#xff0c;操作简便且无需编程基础&#xff1a; 下载安装Excel易用…

Deepseek + RAGFlow 搭建本地知识库问答系统

Deepseek RAGFlow 搭建本地知识库问答系统原因为什么要本地部署RAG模型和微调模型区别本地部署流程1. 下载 ollama &#xff0c;通过ollama把Deepseek模型下载到本地运行。2. 下载RAGFlow 源代码和 Docker &#xff0c;通过Docker部署RAGFlow。3. 在RAGFlow中构建个人知识库并…

elementui附件上传自定义文件列表,实现传完即可预览、下载、删除,二次封装el-upload

背景当前 elementui 的文件上传组件在上传完文件之后只支持删除&#xff0c;用户希望可以看到附件信息&#xff0c;还可以预览自己刚刚上传但未提交的文件&#xff0c;还希望可以下载&#xff0c;因为公司的下载功能当前是通过 OnlyOffice 实现了文件格式转换&#xff0c;所以我…

linux的conda配置与应用阶段的简单指令备注

1.新建某虚拟环境 conda create -n 虚拟环境名 pythonPython版本号 (-y)2.退出当前虚拟环境 conda deactivate3.查看当前conda环境下所有的虚拟环境 conda info --envs4.查看conda版本和位置 conda --versionwhich conda5.激活某个conda虚拟环境 conda activate 虚拟环境名

虚拟化技术 ——KVM

一、KVM 技术简介 KVM&#xff08;Kernel-based Virtual Machine&#xff0c;基于内核的虚拟机&#xff09;是 Linux 内核原生支持的全虚拟化解决方案&#xff0c;依托 CPU 的硬件虚拟化技术&#xff08;Intel VT-x/AMD-V&#xff09;实现高效的虚拟机运行。它将 Linux 内核转…

线程间Bug检测工具Canary

Canary1.Introduction2.Approach2.1.数据依赖分析2.2.线程间依赖分析3.Bug检测4.Evaluation参考文献1.Introduction 主要做跨线程value-flow bug检查&#xff0c;下面代码中两个函数中存在指向关系&#xff1a;1. x→o1x \rightarrow o_1x→o1​, b→o2b \rightarrow o_2b→o2…

AEB 强制来临,东软睿驰Next-Cube-Lite有望成为汽车安全普惠“破局器”

AEB 强制时代正在悄然谱写“普惠安全”的行业底色。日前&#xff0c;备受关注的强制性国家标准《轻型汽车自动紧急制动系统技术要求及试验方法》&#xff08;以下简称“新国标”&#xff09;意见征求阶段已经结束。该标准将替代现行国标GB/T 39901-2021&#xff0c;计划于2028年…

css的white-space: pre

用户从别的地方复制的配置文件&#xff0c;粘贴到输入框内&#xff0c;需要保留原始格式发送给后端。核心步骤&#xff1a;### 1. 格式保持机制 - white-space: pre &#xff1a;这是最关键的CSS属性&#xff0c;确保所有空格、制表符、换行符都被保留 - wrap"off" &…