C++网络爬虫
网络爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。
在这里,我们使用 libcurl 库来对某一特定网页的内容进行抓取。
libcurl 库
安装
首先我们需要介绍一下 libcurl 库
libcurl 库的主要功能就是用不同的协议链接和不同的服务器。
libcurl 当前支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。
在使用 libcurl 库之前,我们需要先安装 libcurl
在 linux 下我们先查看有哪些相应的安装包
在这里我们选择 libcurl-devel 的安装包,如果是 64 位机选择安装
libcurl-devel.x86_64
如果是 32 位机选择安装
libcurl-devel.i686
安装指令都是 yum install + 安装包名
注意 :当我们安装了 libcurl 库之后,当我们在程序中使用了对应的 curl 函数,我们需要在编译的时候加上 -l curl 选项(否则会出现 头文件不存在的情况)
函数
在这里,罗列出我们本次简单爬虫所需要的 函数
- curl_easy_init()函数
这个函数必须是我们C++爬虫中的第一个函数,调用后它将返回一个 CURL 句柄,在这里我们无需关心 CURL 的结构,直接使用即可。
其实这样调用 curl_easy_init 在多线程情况下是不安全的,但是在这里我们先不做讨论。
CURL *curl_easy_init( );
- curl_easy_cleanup()函数
这个函数是和 curl_easy_init()函数配套使用的,目的是释放之前所申请的资源。
void curl_easy_cleanup(CURL * handle );
- curl_easy_setopt()函数
这个函数用于告诉 libcurl 函数如何操作,通过设置选项,而改变操作。
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
参数:
handler 就是 curl_easy_init() 传回的那个 CURL 句柄
option 和 parameter 是相对应的两个参数,在这里我们介绍本次爬虫所需要的参数
option : CURLOPT_URL
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_URL, char *URL);
传入要处理的 URL 指针,URL 应该是一个以 ‘/0’结尾的字符串。
如果在 URL 的头部没有包含相应的传输协议,那么程序将使用一个默认的传输协议(HTTP)
简单的说就是他将会对我们传入的 URL 地址进行处理,并将处理的结果放入 handle 中。
option : CURLOPT_WRITEFUNCTION
size_t write_callback(char *ptr, size_t size,
size_t nmemb, void *userdata);
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_WRITEFUNCTION,
write_callback);
这个参数将传递一个指针指向你的回调函数(write_callback)
当收到需要保存的数据时,这个回调函数将被调用,ptr 是所指向交付的数据,数据的大小等于 size * nmemb
回调函数将返回所处理的实际字节数
userdata 保存数据的缓存空间
option : CURLOPT_WRITEDATA
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_WRITEDATA,
void *pointer);
如果使用CURLOPT_WRITEFUNCTION,那么 pointer 将是在回调函数的第四个参数中得到的指针。
在这前面我们都是对所传入的 URL 文件进行解析,现在我们需要将真正的 HTML 文件抓取下来。
curl_easy_perform()函数
CURLcode curl_easy_perform(CURL * easy_handle );
函数以阻塞的方式执行整个请求。
解析
此时我们已经获得了相应的 HTML 文件,现在我们就需要对获取的 HTML 文件进行解析,我们以西安链家二手房主页进行分析,右键查看源码
在这里我以每个区进行划分,所以需要先对每个区的二手房的网页链接的代码进行提取,在这里需要使用到 boost库的regex 正则表达式
我们找到了相应的后缀链接,在这里需要的正则表达式为
boost::regex reg("/\\w+/\\w+/")
抓取到链接后,和前缀”https//:xa.lianjia.com” 进行字符串合并
现在我们对每一个区的二手房网页信息进行分析
在这里保存的数据就是相应的页数,所以我们同时应该将每一页的url地址获取到,同样通过正则表达式进行分析提取
boost::regex reg("/ershoufang/\\w+/pg\\d/");
这一步做完之后,我将每一页的地址抓取,并获取所有房源的url地址
看起来很杂乱无章,但仔细分析会发现,格式基本都是
href="https://xa.lianjia.com/ershoufang/101102643358.html"
我们同样可以使用正则表达式进行提取
boost::regex reg("https://xa.lianjia.com/ershoufang/\\d+.\\w+");
提取到url地址之后,我们抓取房源地址,并进行分析
可以找到对应的基本信息
在这里,由于我们需要的是单一数据,所以可以使用string的find函数进行查找,并对提取出的字符串进行分析,然后输出。
测试实例