項目設計文檔——爬蟲項目(爬取天氣預報)

一、項目背景以及項目意義

項目背景:

爬蟲技術的核心目的是自動化地從互聯網上采集,提取和存儲數據。網絡爬蟲是一種自動化程序,用于從互聯網上抓取數據并進行處理。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" &…