Linux-基于网络爬虫技术的天气数据查询

一,获取报文数据

复制这个网址 去掉s

并且获取appkey和sign 再替换到到上图二的网址中,打开修改好的网址

这样子我们就可以用了

点击network 找到右下角的ip地址和端口

ip地址:103.205.5.206 端口:80

点击row完全展开,复制全部的报文去写字本(方便等会编辑好放进代码中)

二,要求

实现下图的功能

三,编程思路

1,模块图

项目是干嘛的

用 C 语言手动发 HTTP 请求,把服务器返回的 JSON 字符串里的天气数据抠出来打印。

整体流程:Socket 建连接 → 发 HTTP 请求 → 收 JSON 响应 → 手动解析字段 → 打印


一、网络连接怎么写(每次查询都要走这套)

cs 复制代码
// 1. 建套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);

// 2. 填服务器地址
struct sockaddr_in ser;
bzero(&ser, sizeof(ser));
ser.sin_family      = AF_INET;
ser.sin_port        = htons(80);                     // HTTP 端口 80
ser.sin_addr.s_addr = inet_addr("103.205.5.206");    // k780 服务器 IP

// 3. 连接(注意强转,typedef struct sockaddr* SA 是为了这里)
connect(sockfd, (SA)&ser, sizeof(ser));

// 4. 发请求 / 收响应
send(sockfd, buf, strlen(buf), 0);
bzero(buf, sizeof(buf));
recv(sockfd, buf, sizeof(buf), 0);

// 5. 用完关掉!(get_weather 忘写了这行,会泄漏 fd)
close(sockfd);

二、HTTP 请求怎么构造

请求本质就是一段有格式的纯文本,用 sprintf 把城市名拼进去:

复制代码
char buf[5000] = {0};
sprintf(buf,
    "GET /?app=weather.today&cityNm=%s&appkey=78675&sign=xxx&format=json HTTP/1.1\r\n"
    "Host: api.k780.com\r\n"
    "User-Agent: Mozilla/5.0\r\n"
    "Connection: keep-alive\r\n\r\n",   // 末尾必须有空行 \r\n\r\n
    city);                               // city 是全局变量,set_city() 里改

两个接口只有 app= 这个参数不一样:

  • 实时天气:app=weather.today
  • 生活指数:app=weather.lifeindex

三、JSON 字段怎么提取

服务器返回的是 JSON 字符串,不用任何库,纯靠字符串函数手动抠:

复制代码
// 假设 JSON 里有 "days":"2026-03-06"
char *begin = strstr(buf, "days");      // 找到 key
begin = begin + strlen("days") + 3;    // +3 是跳过 ":"  三个字符(结束引号+冒号+开始引号)
char *end = strchr(begin, '"');         // 找到 value 结束的引号
size_t len = end - begin;
memcpy(days, begin, len);
days[len] = '\0';

为什么 +3? key 后面固定是 ":" 三个字符,跳过后指针就落在 value 的第一个字符上。


四、生活指数的多日遍历

生活指数接口返回的是数组,有好几天的数据,要循环处理:

复制代码
{"result":[{第一天数据},{第二天数据},{第三天数据}]}

思路:遇到 { 记开始,遇到 } 就在这段范围内提取字段打印,遇到 ] 结束循环。

cs 复制代码
char *start = strstr(buf, "result");  // 从 result 字段开始扫
char *obj_start = NULL;

while (1) 
{
    if (*start == '{')      obj_start = start;   // 新对象开始
    else if (*start == '}') {                    // 当前对象结束,提取字段
        // strstr(obj_start, "days") ...
        // strstr(obj_start, "week_1") ...  ← 注意是 week_1 不是 week!
        printf(...);
    }
    if (*(start + 1) == ']') break;  // 数组结束
    start++;
}
close(sockfd);  // 这个函数记得关

五、两个接口字段名的区别(容易搞混)

字段 实时天气接口 生活指数接口
星期 week week_1
紫外线 ❌ 没有 lifeindex_uv_attr
洗车 ❌ 没有 lifeindex_xc_attr
穿衣 ❌ 没有 lifeindex_ct_attr

六、踩过的坑

原因 修复
typedef struct sockaddr *(SA) 编译报错 括号位置不对 改成 typedef struct sockaddr* SA
void 函数里 return 1 报错 void 不能返回值 改成 return;
生活指数 week 字段崩溃 字段是 week_1,用 week 找不到,strstr 返回 NULL 改用 week_1
weather 字段取出来是 weather_curr 的值 strstr("weather") 先匹配到 weather_curr 先提取 weather_curr,再提取 weather
strcmp(city, "\n") 默认城市逻辑没效果 scanf 不读换行符,这个判断永远假 删掉这段逻辑
查询多次后报 too many open files get_weather 没有 close(sockfd) 函数末尾加 close(sockfd)
相关推荐
域中四大2 分钟前
rk3568中修改波特率
linux·运维
互联网推荐官3 分钟前
大模型应用开发的上下文工程与推理链路深度拆解
大数据·运维·人工智能
风曦Kisaki15 分钟前
# Linux Shell 编程入门 Day01:Shell 基础认知、脚本编写规范、变量四大类型、数值运算
linux·运维·chrome
德彪稳坐倒骑驴17 分钟前
SQL连续登录问题
服务器·数据库·sql
云智慧AIOps社区24 分钟前
云智慧亮相第二十八届智能体驱动的GOPS全球运维大会2026 · 深圳站!以运维智能体 Castrel AI (SRE Agent)保障系统稳定可靠!
运维·人工智能·ai agent·运维自动化·sre 智能体
校羽干29 分钟前
ubuntu22.04 安装卸载更新 ollama
运维·服务器
大强同学37 分钟前
Obsidian链接收藏自动化
运维·自动化
MXsoft61840 分钟前
**七八个系统来回切换****?用****一体化运维监控管理平台**
运维
淘矿人1 小时前
2026年4月-DeepSeek V4 vs GPT-5.5深度对比测评:weelinking一键切换实测
服务器·数据库·人工智能·python·gpt·学习·php
忡黑梨1 小时前
eNSP_ACL原理及应用
运维·服务器·网络·tcp/ip·github·负载均衡