C++版网络爬虫
网络爬虫是按照一定规则,自动地抓取万维网信息的程序或脚本。这里用C++语言写一个小程序,实现简单的图片爬取的功能,目的是为了通过这么一个小程序理解爬虫的基本原理及基本流程。其大致实现流程如下:
图一:实现流程图
下面按照流程中的步骤依次用代码实现。
第一步:输入初始的URL
这里要实现的是图片资源的爬取,初始url可以选择一张带图片的网络地址,如http://www.tuxi.com.cn/views-153568413321-1535684133214492.html.其中http://表示协议名称,www.tuxi.com.cn表示主机域名,剩下的部分就表示资源(图片,网页等)在主机上的资源路径
//输入初始url
std::string url;
std::cin >> url;
第二步:创建资源文件夹
创建一个本地文件夹路径,用于存储爬取的资源
//#include <windows.h>
CreateDirectory(L"./Image", NULL);
第三步: URL入队及遍历队列
将初始的url放入队列中,并开始从一个Url开始爬取,首先获取html网页,然后解析网页中的字符串,将包含“http://”字符的字符串提取出来,判断提取的字符串中包含.jpg,.jpeg,.png等图片后缀的字符串,则将其归入资源下载的vector中,待后续下载资源,若不包含的则放入队列中继续循环;
这里注意一点,socket在遍历队列前初始化一次即可,每次遍历一次网页时,连接一次服务器,下载完网页和资源后再释放连接;
//初始化socket
InitSocket();
//将url塞入队列
urlQueue.push(url);
//若队列不为空
while(!urlQueue.empty())
{
//从队列中取出一个URL
std::string curUrl = urlQueue.front();
urlQueue.pop();
//解析URL,获取主机名及资源路径
AnalyseURL(curUrl, strHost, strResPath);
if(strHost.empty())
{
continue;
}
//连接一次,下载 网页,下载资源
Connect();
//下载HTML网页
DownHtmlPage(strHtml);
std::vector<std::string> vecImagesUrl;
//解析网页
AnalyseHtml(strHtml, vecImagesUrl);
//遍历vecImagesUrl中的url,开始下载图片
for(unsigned int i = 0; i < vecImagesUrl.size(); i++)
{
DownImage(vecImagesUrl[i]);
}
}
注意,要是用windows下的socket相关的函数,需要引入Lib,#pragma comment(lib, “ws2_32.lib”),否则编译不通过
//初始化socket
bool InitSocket()
{
//协议版本
WSAData wd;
if(0 != WSAStartup(MAKEWORD(2,2), &wd))
{
return false;
}
if(LOBYTE(wd.wVersion) !=2 || HIBYTE(wd.wVersion) != 2)
{
return false;
}
//创建套接字(流式套接字,TCP)
m_socket = socket(AF_INET, SOCK_STREAM, 0);
if(IN