使用HTTP协议在k780网站上获取天气-----天气预报

news2024/11/20 9:18:14

文章目录

  • 项目介绍
  • 一、项目任务
  • 二、项目流程规划以及代码实现
    • 1.总流程
    • 2.引入库
    • 3.总体流程相关函数
  • 三、功能函数的实现
    • 1. TCP函数
    • 2. 输入城市信息
    • 3. 查询今天天气
    • 4. 查询未来一周天气
    • 5. 查询历史天气
    • 6. 退出
  • 总结


项目介绍


本期主要使用TCP网络编程实现天气预报的功能,这个项目旨在于增进对于TCP编程的掌握以及应用,在这个项目中页用到了一种常见的数据格式—cjson数据格式,能够在这个项目中学会使用cjson数据的解析和使用对日后的工作应该是非常有益的;那么不止这些,还有c语言哦,遇到的棘手的问题几乎都是出自于对于接收到数据的处理,那么从这个项目中处理这个问题(在一串长数据中解析出自己需要的数据)的能力也是需要有的;如果对自己字符串处理的能力不是很自信,那么大家可以尝试来做一下这个项目;

一、项目任务

项目需要实现以下几个功能:
(1)能够输出用户操作的菜单如下:

	1.配置城市                    
	2.查看实时天气信息            
	3.查看未来一周天气            
	4.查看历史天气信息            
	5.退出                        

(2)输入序号对应实现相应的功能

二、项目流程规划以及代码实现

1.总流程

本项目的总体流程图如下:
在这里插入图片描述
每个项目一定是先从整体来把握,再化身庖丁,进行进一步的解析;

2.引入库

首先呢,先把所有的头文件给大家贴出来,其中包含了函数声明:

#ifndef __HEAD_H__
#define __HEAD_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "cJSON.h"

struct sockaddr_in sendaddr;
char city[128];

extern int openLogFile(void);
extern int writeToLog(const char *err);
extern int closeLog(void);

extern int showTerminal(void);
extern int choiceMode(int n);

extern int inputCity(char *city);

extern int createTcpConnect(const char *pIp, int Port);
extern int sendRequestCmd(int sockfd, char *purl);
extern int recvData(int sockfd, char *pRecvbuf, int len);

extern int saveCjsonData(const char *data);
extern char*changeTodata(char *data);
extern int parseCjsonDataOfToday(char *data);
extern int parseCjsonDataOfFuture(char *data);
extern int parseCjsonDataOfHistory(char *data);
extern int searchTodayWeather(const char *city);
extern int searchFutureWeather(const char *city);
extern int searchHistoryWeather(const char *city);
#endif

3.总体流程相关函数

先来看下主函数吧:

#include "head.h"

int main(int argc, const char *argv[])
{	
	int n = 0;

	openLogFile();

	while (1)
	{
		showTerminal();
		printf("请选择:");
		scanf("%d", &n);
		getchar();
		choiceMode(n);
	}

	closeLog();
	return 0;
}

以上代码的步骤是打开日志文件—循环打印终端—用户进行功能选择—循环结束后关闭日志文件;
下面给出日志文件的所有相关代码:

#include "head.h"

FILE *fp = NULL;
//打开日志文件
int openLogFile(void)
{
	fp = fopen("./log.txt", "a");
	if (NULL == fp)
	{
		perror("fail to fopen");
		return -1;
	}
	return 0;
}

//写入日志信息
int writeToLog(const char *err)
{
	char tmpbuff[1024] = {0};
	time_t t;
	struct tm *pp;
	ssize_t nsize = 0;

	time(&t);
	pp = localtime(&t);
	memset(tmpbuff, 0, sizeof(tmpbuff));
	sprintf(tmpbuff, "[%4d-%02d-%02d %02d:%02d:%02d]:%s\n", pp->tm_year+1900, pp->tm_mon+1, pp->tm_mday,pp->tm_hour, pp->tm_min, pp->tm_sec, err);

	printf("%s\n", tmpbuff);
	nsize = fwrite(tmpbuff, strlen(tmpbuff), 1, fp);
	if (-1 == nsize)
	{
		perror("fail to fwrite");
		return -1;
	}
	fflush(fp);

	return 0;
}

//关闭日志文件
int closeLog(void)
{
	fclose(fp);

	return 0;
}

打印终端的函数如下:

//打印终端
int showTerminal(void)
{
	printf("============================\n");
	printf("        天气预报 APP        \n");
	printf("============================\n");
	printf("1.输入需要查询天气的城市\n");
	printf("2.查看当前天气\n");
	printf("3.查看未来一周天气\n");
	printf("4.查看历史天气\n");
	printf("5.退出\n");
	printf("============================\n");

	return 0;
}

进行模式选择如下:

//进行菜单模式选择
int choiceMode(int n)
{
	switch (n)
	{
	case 1 : inputCity(city);break;
	case 2 : searchTodayWeather(city);break;
	case 3 : searchFutureWeather(city);break;
	case 4 : searchHistoryWeather(city);break;
	case 5 : exit(0);break;
	}
	return 0;
}

三、功能函数的实现

1. TCP函数

下面所列出的是所有的TCP通信的相关函数:

//进行TCP链接请求
int createTcpConnect(const char *pIp, int Port)
{
	int sockfd = 0;
	int ret = 0;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		writeToLog("fail to socket");
		return -1;
	}
	sendaddr.sin_family = AF_INET;
	sendaddr.sin_port = htons(Port);
	sendaddr.sin_addr.s_addr = inet_addr(pIp);

	ret = connect(sockfd, (struct sockaddr *)&sendaddr, sizeof(sendaddr));
	if (-1 == ret)
	{
		writeToLog("fail to connect!");
	}

	return sockfd;
}

//向网页发送命令(以GET方法获取)
int sendRequestCmd(int sockfd, char *purl)
{
	char tmpbuff[4096] = {0};
	ssize_t nsize = 0;

	writeToLog("进来了");
	sprintf(tmpbuff, "GET %s HTTP/1.1\r\n", 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: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\n", tmpbuff);
	sprintf(tmpbuff, "%sAccept-Encoding: gzip, deflate\r\n", tmpbuff);
	sprintf(tmpbuff, "%sConnection: keep-alive\r\n\r\n", tmpbuff);

	nsize = send(sockfd, tmpbuff, strlen(tmpbuff), 0);
	if (-1 == nsize)
	{
		writeToLog("fail to send cmd!");
		return -1;
	}

	writeToLog("send success!");

	return sockfd;
}

/*接收数据(此处接收数据有一个弊端在于不能循环用recv去接收k780的数据,因为recv默认是阻塞模式,
它接完后如果对方没有断开,那么它就会持续阻塞导致程序陷入等待状态)
所以最终选择每次只接受一次数据
*/
int recvData(int sockfd, char *pRecvbuf, int len)
{
	ssize_t nsize = 0;
	FILE *fp = NULL;

	fp = fopen("./cjson.txt", "w");
	if (NULL == fp)
	{
		writeToLog("write to cjson.txt failed!");
		return -1;
	}

	writeToLog("进来收取了!");	

	nsize = recv(sockfd, pRecvbuf, len - 1, 0);
	if (nsize <= 0) 
	{
		writeToLog("fail to recv!");
		return -1;
	}
	fwrite(pRecvbuf, 1, nsize, fp);
	fflush(fp);
	writeToLog("recv success!");

	fclose(fp);
	return 0;
}

2. 输入城市信息

这里需要注意city在每个功能中都会使用,所以采用全局变量定义;

//配置城市信息
int inputCity(char *city)
{
	char *ptmp = NULL;

	printf("请输入:");
	memset(city, 0, sizeof(city));
	ptmp = fgets(city, 128, stdin);
	if (NULL == ptmp)
	{
		writeToLog("fgets failed!");
		return -1;
	}
	city[strlen(city) - 1] = 0;
	return 0;
}

3. 查询今天天气

查询天气的流程为:创建套接字请求TCP链接—发送请求命令—接收k780平台反馈的天气信息(含有http包头的cjson数据);

//实现查询今日天气功能
int searchTodayWeather(const char *city)
{
	int sockfd = 0;
	char tmpbuff[4096] = {0};//存放接收到的数据信息
	char *pcontent = NULL;

	sockfd = createTcpConnect("103.205.5.249", 80);	//进行TCP链接请求(103.205.5.249k780提供给用户专门用于访问的ip)
	if (-1 == sockfd)
	{
		writeToLog("fail to createTcpConnect!");
	}
	writeToLog("sockfd success!");

	printf("%s\n", city);
	sprintf(tmpbuff, "/?app=weather.today&weaid=%s&appkey=67618&sign=d83f5d08cb5dea32925dec2cbb077211&format=json", city);		//拼接url
	sockfd = sendRequestCmd(sockfd, tmpbuff);	//向k780网站发送请求
	memset(tmpbuff, 0, sizeof(tmpbuff));
	recvData(sockfd, tmpbuff, sizeof(tmpbuff));	//接受数据信息

	printf("ok!\n");
	pcontent = changeTodata(tmpbuff);			//从收到的所有数据中解析得到完整的cjson数据
	parseCjsonDataOfToday(pcontent);			//对cjson数据进行解析获取需要的信息
	
	close(sockfd);
	return 0;
}

此函数实现的主要功能是从获取到网页含有http包头的数据中解析出cjson数据;
如下图所示,是一个天气的所有信息:
在这里插入图片描述
解析函数如下:


//解析今天的cjson数据
int parseCjsonDataOfToday(char *data)
{
	cJSON *pjson = NULL;
	cJSON *presult = NULL;
	cJSON *pvalue = NULL;

	pjson = cJSON_Parse(data);
	if (NULL == pjson)
	{
		writeToLog("cJSON_Parse failed!");
		return -1;
	}

	presult = cJSON_GetObjectItem(pjson, "result");
	if (NULL == presult)
	{
		writeToLog("cJSON_GetObjectItem failed!");
		return -1;
	}

	printf("=========================\n");
	printf("         天气预报        \n");
	printf("=========================\n");
	pvalue = cJSON_GetObjectItem(presult, "days");
	printf("日期:%s\n", pvalue->valuestring);
	pvalue = cJSON_GetObjectItem(presult, "week");
	printf("星期:%s\n", pvalue->valuestring);
	pvalue = cJSON_GetObjectItem(presult, "citynm");
	printf("城市:%s\n", pvalue->valuestring);
	pvalue = cJSON_GetObjectItem(presult, "temperature_curr");
	printf("温度:%s\n", pvalue->valuestring);
	pvalue = cJSON_GetObjectItem(presult, "humidity");
	printf("湿度:%s\n", pvalue->valuestring);

	return 0;
}
//从获取到网页含有http包头的数据中解析出cjson数据
char*changeTodata(char *data)
{
	char *begin = NULL;
	char *end = NULL;
	char tmpbuff[4096] = {0};

	begin = strstr(data, "\r\n\r\n");
	begin += 4;
	begin = strstr(begin, "\r\n");
	begin += 2;
	end = strstr(begin, "\r\n");
	
	strncpy(tmpbuff, begin, end - begin + 1);
	
	strcpy(data, tmpbuff);

	return data;	
}

结果如下,得到需要的数据:
在这里插入图片描述
打印今天天气的功能如下:
在这里插入图片描述

4. 查询未来一周天气

此功能和上一个功能的实现是非常相似的,不同点在于数据格式不同,所以解析的方法也不同;

//实现查找未来一周天气功能
int searchFutureWeather(const char *city)
{
	int sockfd = 0;
	char tmpbuff[10 * 4096] = {0};
	FILE *fp = NULL;
	off_t len;
	char *pcontent = NULL;

	sockfd = createTcpConnect("103.205.5.249", 80);
	if (-1 == sockfd)
	{
		writeToLog("fail to createTcpConnect!");
	}
	writeToLog("sockfd success!");
	printf("%s\n", city);
	memset(tmpbuff, 0, sizeof(tmpbuff));
	sprintf(tmpbuff, "/?app=weather.future&weaid=%s&appkey=67618&sign=d83f5d08cb5dea32925dec2cbb077211&format=json", city);
	sendRequestCmd(sockfd, tmpbuff);
	memset(tmpbuff, 0, sizeof(tmpbuff));
	recvData(sockfd, tmpbuff, sizeof(tmpbuff));
	
	pcontent = changeTodata(tmpbuff);
	parseCjsonDataOfFuture(pcontent);

	close(sockfd);
	return 0;
}

解析函数如下:

//解析未来一周的cjson数据
int parseCjsonDataOfFuture(char *data)
{
	cJSON *pjson = NULL;
	cJSON *presult = NULL;
	cJSON *pvalue = NULL;
	cJSON *parray = NULL;
	int i = 0;

	pjson = cJSON_Parse(data);
	if (NULL == pjson)
	{
		writeToLog("cJSON_Parse failed!");
		return -1;
	}

	presult = cJSON_GetObjectItem(pjson, "result");
	if (NULL == presult)
	{
		writeToLog("cJSON_GetObjectItem failed!");
		return -1;
	}

	printf("=========================\n");
	printf("         天气预报        \n");
	printf("=========================\n");
	for (i = 0;i < 7; ++i)
	{
		printf("=========================\n");
		parray = cJSON_GetArrayItem(presult, i);

		pvalue = cJSON_GetObjectItem(parray, "days");
		printf("日期:%s\n", pvalue->valuestring);
		pvalue = cJSON_GetObjectItem(parray, "week");
		printf("星期:%s\n", pvalue->valuestring);
		pvalue = cJSON_GetObjectItem(parray, "citynm");
		printf("城市:%s\n", pvalue->valuestring);
		pvalue = cJSON_GetObjectItem(parray, "temperature");
		printf("温度:%s\n", pvalue->valuestring);
		pvalue = cJSON_GetObjectItem(parray, "humidity");
		printf("湿度:%s\n", pvalue->valuestring);
		printf("=========================\n");
	}
	return 0;
}

实现功能的结果如下:
在这里插入图片描述

5. 查询历史天气

查询历史天气的cjson数据如下:
在这里插入图片描述

//实现查找历史天气功能
int searchHistoryWeather(const char *city)
{
	int sockfd = 0;
	char tmpbuff[30 * 4096] = {0};
	char tmpbuff1[30 * 4096] = {0};
	FILE *fp = NULL;
	off_t len;
	char *pcontent = NULL;

	sockfd = createTcpConnect("103.205.5.249", 80);
	if (-1 == sockfd)
	{
		writeToLog("fail to createTcpConnect!");
	}
	writeToLog("sockfd success!");
	printf("%s\n", city);
	memset(tmpbuff, 0, sizeof(tmpbuff));
	sprintf(tmpbuff, "/?app=weather.history&weaid=1&dateYmd=20220101&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json");
	sendRequestCmd(sockfd, tmpbuff);
	memset(tmpbuff, 0, sizeof(tmpbuff));
	recvData(sockfd, tmpbuff, sizeof(tmpbuff));
	printf("tmpbuff = %s", tmpbuff);
	
	pcontent = changeTodata(tmpbuff);
	printf("pcontent = %s\n", pcontent);
	parseCjsonDataOfHistory(pcontent);

	close(sockfd);
	return 0;
}

由于历史cjson数据格式与前两种功能的cjson数据格式不同,所以具体解析方式也不相同;

//解析历史cjson数据
int parseCjsonDataOfHistory(char *data)
{
	cJSON *pjson = NULL;
	cJSON *presult = NULL;
	cJSON *pvalue = NULL;
	cJSON *parray = NULL;
	int i = 0;

	printf("data = %s\n", data);
	printf("=================================================================\n");
	pjson = cJSON_Parse(data);
	if (NULL == pjson)
	{
		writeToLog("cJSON_Parse failed!");
		return -1;
	}

	presult = cJSON_GetObjectItem(pjson, "result");
	if (NULL == presult)
	{
		writeToLog("cJSON_GetObjectItem failed!");
		return -1;
	}

	presult = cJSON_GetObjectItem(presult, "dtList");

	printf("=========================\n");
	printf("         天气预报        \n");
	printf("=========================\n");
	for (i = 0;i < 12; ++i)
	{
		printf("=========================\n");
		parray = cJSON_GetArrayItem(presult, i);

		pvalue = cJSON_GetObjectItem(parray, "upTime");
		printf("日期:%s\n", pvalue->valuestring);
		pvalue = cJSON_GetObjectItem(parray, "wtTemp");
		printf("温度:%s\n", pvalue->valuestring);
		pvalue = cJSON_GetObjectItem(parray, "wtHumi");
		printf("湿度:%s\n", pvalue->valuestring);
		pvalue = cJSON_GetObjectItem(parray, "wtNm");
		printf("天气:%s\n", pvalue->valuestring);
		printf("=========================\n");
	}
	return 0;
}

由于上面接取数据的时候只接收了12组数据,所以解析的部分结果如下:
在这里插入图片描述

6. 退出

我们需要做的操作非常简单,只需要exit(0);结束进程即可;

总结

本项目的所有功能实现在上文中均有展示,如果想提高网络编程以及字符串处理,http协议的同学可以上手练习一下这个项目,对于正在学习的小伙伴们来说是的非常有帮助的;本项目也有以下几个不足:
(1)在接收数据时只做到的单词接收,大家可以将recv改进为非阻塞模式解决这个问题;
(2)k780网站的接口查询历史天气是需要收费的,所以在本期分享中我用的是测试接口,没有付费;
最后,各位小伙伴们如果喜欢我的分享可以点赞收藏哦,你们的认可是我创作的动力,一起加油!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Html5的在线资料库的设计与实现(asp.NET,SQLServer)

在线资料库系统采用.NET开发平台进行开发&#xff0c;开发工具采用Microsoft Visual Studio 2010集成开发环境&#xff0c;后台编程语言采用C#编程语言来进行编程开发&#xff0c;数据库我们采用当下流行的SQL Server 2008数据库管理系统来存放平台中的数据信息&#xff0c;整个…

【Windows设置篇】字符集-简繁体的切换

【Windows设置篇】字符集-简繁体的切换 微软自带键盘&#xff0c;有次傻啦吧唧的一直找繁体切换简体的方法&#xff0c;进设置里面切换地区&#xff0c;更换地址也不行&#xff0c;后面才发现是在"字符集"里面切换—【蘇小沐】 文章目录 【Windows设置篇】字符集-简…

Maven jar 包下载失败问题处理【配置Maven国内源】

前言 很多同学在Maven里下载一些依赖的时候&#xff0c;即下载【jar 包】的时候总是会出现一些问题&#xff0c;这里专门做一个教程讲解一下 其实这和你的Maven配置是有关系的&#xff0c;因为Maven是一个国际站点&#xff0c;它的仓库是在国外的&#xff0c;所以我们有时候在下…

【C++】函数高级 - 默认参数,占位参数,函数重载基本语法,函数重载注意事项

No.Contents1【C】基础知识 - HelloWorld&#xff0c;注释&#xff0c;变量&#xff0c;常量&#xff0c;关键字&#xff0c;标识符2【C】数据类型 - 整型&#xff0c;sizeof&#xff0c;实型&#xff0c;字符型&#xff0c;转义字符&#xff0c;字符串类型&#xff0c;布尔类型…

chatgpt赋能python:Python中浮点数的定义

Python中浮点数的定义 什么是浮点数&#xff1f; 在计算机科学中&#xff0c;浮点数&#xff08;floating-point number&#xff09;是一种用于表示实数的近似值的数值类型。Python中的浮点数是由整数部分和小数部分组成的&#xff0c;可以使用小数点来表示。例如&#xff0c…

考研C语言第七章

7.2函数的声明定义&#xff0c;函数的分类和调用 1、函数声明要在main函数上面&#xff0c;这样main函数才可以进行调用 第一节课主要就学了函数的调用&#xff0c;项目在开发的时候分工用的比较多 主要结构&#xff1a; func.c里面进行函数的定义 不是很重要&#xff0c;进…

IDEA+Mysql+Sqlserver安装步骤_kaic

下载Intellij 开发工具&#xff0c;如果有请检查软件是否过期&#xff0c;如果过期卸载电脑上的Intellij软件。卸载步骤&#xff1a; 打开控制面板&#xff0c;选择卸载程序找到Intellij右键卸载 如果没有请保存文档中的Intellij.zip压缩包,进行安装&#xff0c;安装步骤 双…

查看 HTTP 请求的数据.

文章结构 如果是 GET 请求如果是 POST 请求方法1&#xff1a;DEBUG 窗口&#xff08;**爽、超级爽、吴迪爽**&#xff09;&#xff1a;方法2&#xff1a;写方法读取流中数据&#xff08;繁琐&#xff0c;难用&#xff09;&#xff1a; 我们可能会碰到 MVC 拿不到前端的参数&…

何时加索引,性别字段和逻辑删除字段应不应该加

首先哪些地方加索引&#xff08;按照sql执行顺序写&#xff09; 1、from表扫描连接处索引 2、where后条件去走索引 3、group by加索引 4、select查询不用加 5、order by排序加索引 &#xff08;对于第四点&#xff0c;覆盖索引&#xff1a;查询的字段都被索引覆盖&#xff0c;…

chatgpt赋能python:Python中用什么表示空格

Python中用什么表示空格 空格在编程中是一个非常重要的概念&#xff0c;特别是在Python中。Python是一门非常灵活的语言&#xff0c;空格是它语法的一个关键组成部分。今天我们将探讨的是Python中用什么表示空格。 空格是Python中的一个重要概念&#xff0c;它被用来表示代码…

spdk记录

spdk记录 hello_bdev命令行参数 往期文章&#xff1a; spdk环境搭建 hello_bdev 代码路径&#xff1a;examples/bdev/hello_world/hello_bdev.c 可执行文件路径&#xff1a;build/examples/hello_bdev 刚开始直接执行hello_bdev显示找不到Malloc0 ./build/examples/hello_b…

Vue3-devtools开发者工具正确安装方法

目录 前言&#xff1a;1、下载安装2、添加扩展 前言&#xff1a; 最近在学习Vue3&#xff0c;学习Vue3自然离不开调试工具Vue3-Devtools&#xff0c;所以我们需要来下载这个调试工具并放入谷歌浏览器里的扩展程序里面。帮助我们更好的调试vue3里的程序。 1、下载安装 Github下…

【C#图解教程】第四章 类型、存储和变量 学习笔记总结

类型 C#是一组类型声明&#xff0c;这个与第三章&#xff1a;命名空间就是一组类型声明可以一起理解。类型是一个用来创建数据结构的模板&#xff1a; 使用这个模板创建对象的过程叫做实例化&#xff0c;所以创建的对象也叫实例 类型成员 简单类型可能只包含一个数据成员&…

JavaEE HTTPS加密原理

HTTPS加密原理✿✿ヽ(▽)ノ✿ 文章目录 JavaEE & HTTPS加密原理1. 为什么要加密2. HTTPS加密原理2.1 初始想法2.2 引入非对称加密2.3 中间人攻击2.4 引入证书 JavaEE & HTTPS加密原理 1. 为什么要加密 例子&#xff1a;&#xff08;运营商劫持&#xff09; 你可能经常…

C语言system()函数

文章目录 C语言system()函数system(“pause”)system(“color num1num2”)system(“cls”)system(“title name”)system(“time /T”) & system(“date /T”) C语言system()函数 头文件&#xff1a; #include<stdlib.h>system(“pause”) 作用&#xff1a;暂停程序进…

AI Canon精选资源清单;带AI功能的PS安装文件与教程;讯飞星火10月对标 ChatGPT;直播换脸工具盘点 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; AI Canon&#xff1a;人工智能精选资源清单 思维导图 ShowMeAI知识星球资源编码&#xff1a;R106 AI Canon 是由美国著名的风投机构 …

【靶场实战】Vulnhub - JANGOW: 1.0.1 靶标实战

靶场地址&#xff1a;https://www.vulnhub.com/entry/jangow-101,754/ 靶场IP&#xff1a;192.168.160.215 信息收集 使用Nmap对目标进行扫描 Nmap -sV -O -p- 192.168.160.215 经过漫长的等待扫描完成&#xff0c;该靶标开启了21、80两个端口&#xff0c;21端口运行服务为f…

chatgpt赋能python:Python中按钮的位置摆放

Python中按钮的位置摆放 在Python应用程序中&#xff0c;按钮是常见的交互元素之一。按钮通常用于响应用户的操作&#xff0c;例如提交表单或执行某些功能。然而&#xff0c;在设计应用程序时&#xff0c;按钮的位置是一个重要的问题&#xff0c;因为它将直接影响用户体验和应…

chatgpt赋能python:Python中的画图——创建漂亮的可视化图像

Python中的画图——创建漂亮的可视化图像 Python是一个高度可编程的语言&#xff0c;因此它非常适合用于创建各种类型的可视化。 在本文中&#xff0c;我们将介绍Python中的画图。我们将讨论如何使用Python和一些流行的数据可视化库来创建漂亮的可视化图像。我们还将探讨如何…

【PWN · ret2libc】[2021 鹤城杯]babyof

Linux_64的经典ret2libc题目&#xff0c;有必要好好整理总结一下其中的流程和注意点 目录 前言 一、题目重述 二、exp&#xff08;思考与理解在注释&#xff09; 三、经验总结 攻击步骤: 注意要点 四、疑问 前言 64位Linux和32位Linux确乎有着关于参数传递上的不同&a…