C++实现网络爬虫

原理

根据起始url得到网页的HTML代码。解析此HTML代码得到新的URL和图片资源(任何有用的资源)的地址,新的URL继续此过程。下载图片在一个新的线程里。

代码

CHttp.h

#include
#include
#include
#include
//#include在windows里边
using namespace std;

#pragma comment(lib,"ws2_32.lib")//网络的库

class CHttp
{
private:
	string m_host;
	string m_object;
	SOCKET m_socket;
	bool AnalyseUrl(string url);//解析URL\http
	bool AnalyseUrl2(string url);//\https
	bool init();//初始化套接字
	bool Connect();//连接web服务器
public:
	CHttp(void);
	~CHttp(void);
	string FetchGet(string url);//通过Get方式获取网页
	void AnalyseHtml(string html);//解析网页,获得图片地址和其他的链接
};

CHttp.cpp

#include "CHttp.h"

CHttp::CHttp(void)
{

}


CHttp::~CHttp(void)
{
	closesocket(m_socket);
	WSACleanup();
}

//解析URL\http
bool CHttp::AnalyseUrl(string url)
{
	if(string::npos == url.find("http://"))
		return false;
	if(url.length()<=7)
		return false;
	int pos =url.find('/',7);
	if(pos==string::npos)
	{
		m_host=url.substr(7);
		m_object='/';
	}
	else
	{
		m_host=url.substr(7,pos-7);
		m_object=url.substr(pos);
	}
	if(m_host.empty())
		return false;
	return true;
}

//解析URL\https
bool CHttp::AnalyseUrl2(string url)
{
	if(string::npos == url.find("https://"))
		return false;
	if(url.length()<=8)
		return false;
	int pos =url.find('/',8);
	if(pos==string::npos)
	{
		m_host=url.substr(8);
		m_object='/';
	}
	else
	{
		m_host=url.substr(8,pos-8);
		m_object=url.substr(pos);
	}
	if(m_host.empty())
		return false;
	return true;
}

bool CHttp::init()
{
	//1 请求协议版本
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (LOBYTE(wsaData.wVersion) != 2 ||
		HIBYTE(wsaData.wVersion) != 2){
			printf("请求协议版本失败!\n");
			return false;
	}
	//printf("请求协议成功!\n");
	//2 创建socket
	m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (SOCKET_ERROR == m_socket){
		printf("创建socket失败!\n");
		WSACleanup();
		return false;
	}
	//printf("创建socket成功!\n");
	return true;
}

//连接web服务器
bool CHttp::Connect()
{
	//DNS服务器:将域名解析成IP地址
	hostent *p = gethostbyname(m_host.c_str());
	if(p==NULL)
		return false;
	SOCKADDR_IN sa;
	sa.sin_family=AF_INET;
	sa.sin_port=htons(80);//http的默认端口,https的默认端口443
	memcpy(&sa.sin_addr,p->h_addr,4);

	if(-1==connect(m_socket,(SOCKADDR*)&sa,sizeof(sa)))
	{
		cout<<"服务器连接失败"< p;
				p.push(src);
				extern void loadImage();
				CreateThread(NULL, NULL,(LPTHREAD_START_ROUTINE)loadImage, 
					NULL, NULL, NULL);
			}
			/*system("pause");*/
		}
		startIndex=endIndex+1;
		//system("pause");
	}

	startIndex =0;
	//找到其他URL地址
	for(int pos=0;pos q;
				q.push(url);
				//cout<

main.cpp

#include "CHttp.h"
#include 

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

queue q;//url队列
queue p;//图片url队列

void StartCatch(string url);
int main()
{
	cout<<"*****************************************"<>url;
	url="http://desk.zol.com.cn/";//爬的是这个网站,可自行修改
	//开始抓取
	StartCatch(url);

	system("pause");
	return 0;
}

void StartCatch(string url)
{
	
	q.push(url);

	while(!q.empty())
	{
		//取出url
		string currenturl = q.front();
		q.pop();

		CHttp http;
		//发送一个Get请求
		string html=http.FetchGet(currenturl);
		//cout<

大家也可以访问我的个人博客豆浆and油条er、个人公众号搜索:豆浆and油条er,或者直接扫描头像

你可能感兴趣的:(C语言,C++)