这是一个我的课程设计,作为一个入门选手,想把自己的一些东西写给自己之后复习用。老师本来给的题目是:向http发送一个请求,然后看它返回啥东西。
内容为用c语言简单的爬取一个天气网站:http://t.weather.sojson.com/api/weather/city/101030100
每段代码都给出了详细的注释。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#include<locale.h>
//locale.h处理多种文字,可以通过 <locale.h> 头文件中的 setlocale() 函数进行地域设置,改变程序的语言环境。
//原来输出是乱码的
#pragma comment(lib, "ws2_32.lib") //加载 ws2_32.dll
#pragma warning(disable:4996)
#define BUF_SIZE 30000
int main()
{
setlocale(LC_ALL, "en_US.UTF-8"); //en-US就是一个专有名称,它对应的是美国英语
//初始化DLL
WSADATA wsaData;//?
WSAStartup(MAKEWORD(2, 2), &wsaData); //指定使用的版本号,返回关于winsock实现的详细信息
//创建套接字
SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // PF = Protocol Family,流式套接字,该套接口使用的特定协议
//向服务器发起请求
SOCKADDR_IN sockAddr; //结构体,里面包含以下东西
memset(&sockAddr, 0, sizeof(sockAddr)); //每个字节都用0填充
sockAddr.sin_family = PF_INET; //表示使用IP地址族;
sockAddr.sin_addr.s_addr = inet_addr("61.139.65.250"); //是网络字节序的32位IP地址
sockAddr.sin_port = htons(80); //是以网络字节序表示的16位端口号;
connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
//s将要建立连接的套接口字,
//一个指向远端套接口地址结构(sockaddr_in)的指针,表示s套接字欲与其建立一条连接;
//是服务器端的地址长度,即name的长度。
const char* request = "GET /api/weather/city/101030100 HTTP/1.1\r\n"
"Host: t.weather.sojson.com\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36\r\n"
"\r\n";
//获取用户输入的字符串并发送给服务器
send(sock, request, strlen(request), 0);
//用于标识已建立连接的套接字;
// 是一个缓冲区,内有将要发送的数据
// 即将发送的缓冲区中的字节数
Sleep(5000);
//接收服务器传回的数据,从套接口上接收数据
char bufRecv[BUF_SIZE] = { 0 };
recv(sock, bufRecv, BUF_SIZE, 0);
//已建立连接的套接字
//为用于接收数据的缓冲区
//为缓冲区的长度
//输出接收到的数据
printf("Message form server: %s\n", bufRecv);
//关闭套接字,以释放
//与该套接口关联的所有资源,包括等候处理的数据
closesocket(sock);
//终止使用 DLL
WSACleanup();
system("pause");
return 0;
}