C++ 爬取网页内容进行IP查询(附带serve+client+查询主机所有IP+判断IP是否联网的程序)

#ifndef __H_HTML_PARSE_H__
#define __H_HTML_PARSE_H__

#pragma once

#include <Windows.h>
#include <WinInet.h>
#include <string>
#include <cstdio>

class hHtmlParse {
	std::string data;
	int p;
public:
	//构造函数,传入HTML代码
	hHtmlParse(std::string& data);
	//获取网页的编码方式
	bool GetCharset(std::string& s);
	//设置当前解析位置
	bool SetPos(const char* find);
	//设置当前解析位置(反向查找目标位置)
	bool SetPos_LastOf(const char* find);
	//查找是否存在目标位置,不会更新当前位置
	bool find(const char* find);
	//匹配一串字符串,使用sscanf_s获取
	bool MatchString(const char* match, std::string& s);
	//获取当前电脑IP地址
	static bool GetLocalIp(std::string& ip);
	//查询某地址或某域名信息
	static bool GetAddrMessage(const wchar_t* addr, std::string& data);
	//关键函数,获取lpURL指向的地址的HTML代码,并存入data中
	static bool UrlGetHtml(LPCWSTR lpURL, std::string& data);
};

#endif //__H_HTML_PARSE_H__

爬取网页内容上面是头文件,下面是源文件

#include "htmlparse.h"

#pragma comment(lib, "WinInet.lib")

hHtmlParse::hHtmlParse(std::string& data) {
	this->data = data;
	this->p = 0;
}

bool hHtmlParse::GetCharset(std::string& s) {
	this->SetPos("charset=");
	return this->MatchString("%*[\"]%[^\"]", s);
}

bool hHtmlParse::SetPos(const char* find) {
	int t = this->data.find(find, p);
	if (-1 == t) return false;
	this->p = t + strlen(find);
	return true;
}

bool hHtmlParse::SetPos_LastOf(const char* find) {
	int t = this->data.rfind(find);
	if (-1 == t) return false;
	this->p = t + strlen(find);
	return true;
}

bool hHtmlParse::find(const char* find) {
	int t = this->data.find(find, p);
	return t != -1;
}

bool hHtmlParse::MatchString(const char* match, std::string& s) {
	return sscanf_s(&data.c_str()[p], match, const_cast<char*>(s.c_str()), s.capacity()) > 0;
}

bool hHtmlParse::GetLocalIp(std::string& ip) {
	std::string page, match;
	page.resize(512);
	match.resize(16);
	if (!hHtmlParse::UrlGetHtml(L"http://1111.ip138.com/ic.asp", page)) return false;
	hHtmlParse hp(page);
	hp.SetPos("<center>");
	hp.MatchString("%*[^0-9]%[0-9.]", match);
	ip.clear();
	ip = match.c_str();
	return true;
}

bool hHtmlParse::GetAddrMessage(const wchar_t* addr, std::string& data) {
	data.clear();
	std::wstring link = L"http://www.ip138.com/ips138.asp?ip=";
	std::string page, match;
	link += addr;
	page.resize(16384);
	match.resize(64);
	if (!hHtmlParse::UrlGetHtml(link.c_str(), page)) return false;
	hHtmlParse hp(page);
	hp.SetPos_LastOf("<table");
	hp.SetPos("<td");
	hp.SetPos("<td");
	bool b = true;
	if (hp.find(">>")) {
		b = false;
		hp.SetPos(">>");
		hp.MatchString("%*[^0-9]%[0-9.]", match);
		data = match.c_str();
	}
	hp.SetPos("<ul");
	while (hp.find("<li")) {
		hp.SetPos(":");
		hp.MatchString("%[^<]", match);
		if (b) 
			b = false; 
		else data += "\n";
		data += match.c_str();
	}
	return true;
}

bool hHtmlParse::UrlGetHtml(LPCWSTR lpURL, std::string& data) {
	HINTERNET hSession = InternetOpenW(L"EmotionSniffer", NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE);
	if (!hSession) return FALSE;
	HINTERNET hFile = InternetOpenUrlW(hSession, lpURL, NULL, NULL, INTERNET_FLAG_RELOAD, NULL);
	if (!hFile) {
		InternetCloseHandle(hSession); return FALSE;
	}
	DWORD dwW = 0, dwR = 0;
	int capacity = data.capacity();
	do {
		dwW += dwR;
		if (dwW != 0 && dwR == 0) break;
		if (dwW + 1024 >= capacity) data.resize(capacity *= 2);
	} while (InternetReadFile(hFile, (LPVOID)(data.c_str() + dwW), 1024, &dwR));
	const_cast<char*>(data.c_str())[dwW] = '\0';
	InternetCloseHandle(hFile);
	InternetCloseHandle(hSession);
	return TRUE;
}

服务端程序

//serve
#include <stdio.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll
int main(){
	//初始化 DLL
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	//创建套接字
	SOCKET servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	//绑定套接字
	sockaddr_in sockAddr;
	memset(&sockAddr, 0, sizeof(sockAddr));  //每个字节都用0填充
	sockAddr.sin_family = PF_INET;  //使用IPv4地址
	sockAddr.sin_addr.s_addr = inet_addr("192.168.43.137");  //具体的IP地址
	sockAddr.sin_port = htons(1234);  //端口
	
	
	bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
	//进入监听状态
	listen(servSock, 20);
	//接收客户端请求
	SOCKADDR clntAddr;
	int nSize = sizeof(SOCKADDR);
	SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);
	//向客户端发送数据
	char *str = "Hello World!";
	send(clntSock, str, strlen(str) + sizeof(char), NULL);
	//关闭套接字
	closesocket(clntSock);
	closesocket(servSock);
	//终止 DLL 的使用
	WSACleanup();
	return 0;
}

客户端程序

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
typedef struct sockaddr_in sockaddr_in;
#pragma comment(lib, "ws2_32.lib")  //加载 ws2_32.dll
int main(){
	//初始化DLL
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	//创建套接字
	SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	//向服务器发起请求
	sockaddr_in sockAddr;
	memset(&sockAddr, 0, sizeof(sockAddr));  //每个字节都用0填充
	sockAddr.sin_family = PF_INET;
	sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	sockAddr.sin_port = htons(1234);
	
	
	connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
	//接收服务器传回的数据
	char szBuffer[MAXBYTE] = { 0 };
	recv(sock, szBuffer, MAXBYTE, NULL);
	//输出接收到的数据
	printf("Message form server: %s\n", szBuffer);
	//关闭套接字
	closesocket(sock);
	//终止使用 DLL
	WSACleanup();
	system("pause");
	return 0;
}

查询当前主机的所有IP

#include <iostream>
#include <string>
#include <vector>
#include <atlstr.h>
#include <Netlistmgr.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char* argv[])
{
	CString m_IP;              //IP地址临时变量
	CString m_LocalIP;
	char PCnameBuffer[128];    //获得本地计算机名
	CString m_PCname;

	WSAData data;              //初始化:如果不初始化,以下代码将无法执行
	if (WSAStartup(MAKEWORD(1, 1), &data) != 0)
	{
		cout << "初始化错误,无法获取主机信息..." << endl;
	}
	else
	{
		if (0 == gethostname(PCnameBuffer, 128))
		{
			m_PCname = PCnameBuffer;
			struct hostent* pHost;  //获得本地IP地址
			pHost = gethostbyname(PCnameBuffer);  //pHost返回的是指向主机的列表

			for (int i = 0; pHost != NULL&&pHost->h_addr_list[i] != NULL; i++)
			{
				//得到指向ip的psz变量
				LPCSTR psz = inet_ntoa(*(struct in_addr *)pHost->h_addr_list[i]);
				m_IP += psz;
			}
			m_LocalIP = m_IP;
		}

		else
		{
			cout << "获取主机信息失败..." << endl;
		}
	}

	USES_CONVERSION;        //声明使用T2A函数
	//char* ComputerName = T2A(m_PCname);   //T2A函数,将Cstring类型转换为char*
	//char* ComputerIp = T2A(m_LocalIP);
	std::string strTempData = (CStringA)m_LocalIP;
	cout << strTempData << endl;
	system("pause");
	return 0;
}

判断当前IP是否联网

//判断IP是否联网
#include<iostream>  
#include <WINSOCK2.H>  
#pragma comment(lib,"ws2_32.lib")  
#define LEN 1024    //接收数据的大小  
using namespace std;


int main()
{
	//加载套接字库  
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD(1, 1);    //初始化Socket动态连接库,请求1.1版本的winsocket库  

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0) {
		return 0;
	}

	if (LOBYTE(wsaData.wVersion) != 1 ||   //判断请求的winsocket是不是1.1的版本  
		HIBYTE(wsaData.wVersion) != 1) {
		WSACleanup();          //清盘  
		return 0;                   //终止对winsocket使用  
	}




	//WSADATA ws;  
	//WSAStartup(MAKEWORD(2,2),&ws);//  
	char http[60] = "www.baidu.com";           //访问谷歌网页  
	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//建立socket  

	struct sockaddr_in localaddr;//绑定本机的ip
	localaddr.sin_family = AF_INET;
	localaddr.sin_addr.s_addr = inet_addr("192.168.43.137");//绑定本地ip地址
	localaddr.sin_port = htons(1234);  // Any local port will do
	bind(sock, (struct sockaddr *)&localaddr, sizeof(localaddr));

	if (sock == INVALID_SOCKET){
		printf("invalid socket !");
		return 0;
	}

	sockaddr_in hostadd;
	hostent* host = gethostbyname(http);//取得主机的IP地址  
	if (host == NULL)
	{
		cout << "主机处于没有联网状态;" << endl;
		return 0;
	}
	cout << "主机处于联网状态,现在可以进行通信!" << endl;
	memcpy(&hostadd, host->h_addr, sizeof(hostadd));//将返回的IP信息Copy到地址结构  
	hostadd.sin_family = AF_INET;
	hostadd.sin_port = htons(80);
	//hostadd.sin_addr.s_addr = inet_addr("192.168.43.137");  //具体的IP地址



	char buf[LEN] = "GET / HTTP/1.1\r\nHost: ";//构造Http请求数据包  
	strcat_s(buf, inet_ntoa(hostadd.sin_addr));
	strcat_s(buf, " \r\nContent-Length: 10\r\n\r\n");
	strcat_s(buf, "Connection:close");
	int time = 1000;    //超时时间  
	setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&time, sizeof(time));
	if (connect(sock, (sockaddr*)&hostadd, sizeof(hostadd)) == SOCKET_ERROR)//连接请求  
	{
		cout << "与网页建立连接失败!" << endl;
		return 0;
	}
	if (SOCKET_ERROR == send(sock, buf, strlen(buf) + 1, 0))//发送构造好的Http请求包  
	{
		cout << "发送数据包失败!" << endl;
		return 0;
	}
	memset(buf, 0, LEN);
	recv(sock, buf, LEN, 0);               //接收返回的数据  
	cout << "从网页中获取的数据为:" << buf;
	system("pause");
	closesocket(sock);
	
	WSACleanup();
	system("pause");
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Naruto

你的鼓励是我的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值