分布式爬虫实验设计文档
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
分布式网络爬虫实验
五组赵成龙、黄莹
一、需求分析 (2)
二、实验架构及原理 (2)
三、模块设计及代码实现 (3)
3.1爬取网页模块设计 (3)
3.1.1 DNS解析 (4)
3.1.2 Socket连接 (4)
3.1.3 发送HTTP请求头并获得相应 (6)
3.2网页解析模块设计 (7)
3.2.1正则表达式的设计 (8)
3.2.2测试用例的设计 (8)
3.2.3利用Regex库提取网页URL (8)
3.2.4利用Pcre库提取网页URL (10)
四、心得体会 (12)
一、需求分析
随着国际互联网的迅速发展,网上的信息越来越多,全球网页数量超过20亿,每天新增加730万网页。要在如此浩瀚的信息海洋里寻找信息,就像“大海捞针”一样困难。在实际生活中我们经常会使用像百度、Google这些搜索引擎检索各种信息,搜索引擎正是为了解决这个问题而出现的技术,而网络爬虫正是搜索引擎所需要的关键部分
既然百度、Google这些搜索引擎巨头已经帮我们抓取了互联网的大部分信息,为什么还要自己写爬虫呢?因为深入整合信息的需求是广泛存在的,在企业中,爬虫抓取下来的信息可以作为数据仓库多维展现的数据源,也可以作为数据挖掘的来源,甚至有人为了炒股,专门抓取股票信息。这些实际问题的解决所需要的根本技术就是分布网络爬虫。
本次实验主要的内容就是利用IO复用抓取网页,并多线程的分析每个抓取到的网页所包含的URL信息,通过消息队列将抓取网页的部分和分析网页部分进行通信,最终记录下160000网页中所包含的所有URL,实现分布式网络爬虫。
二、实验架构及原理
本实验分为两个模块:爬取网页模块、网页分析模块。实验架构如图2.1所示
图2.1 分布是网络爬虫框架
爬取网页模块采用socket通信方式实现客户端与服务器的通信:首先将客户端与服务器进行三次握手后建立连接,客户端发送HTTP请求头,服务器端收到客户端请求后,进行HTTP响应,发送相应的网页信息,客户端收到服务器的响应后将所获得网页文件交给网页分析模块进行处理并提取URL。流程图如图所示:
图2.2 爬取网页模块流程图
网页分析模块主要工作如下图流程图所示。而本模块的网页分析处理主要在于对抓取到的HTML文件的内容进行URL的提取,我们主要运用正则表达式进行字符串的匹配操作。通过采用Regex正则表达式库和Pcre正则表达式库进行了两种尝试,并根据网页的情况设计了测试用例,进行程序的检验。
图2.3 网页分析模块流程图
三、模块设计及代码实现
3.1爬取网页模块设计
3.1.1 DNS解析
考虑到网页爬取域名转换的问题,需要将URL进行DNS解析。DNS解析是将一一对应的域名与IP地址进行转换的一种技术,域名解析需要由专门的域名解析服务器来完成,整个过程是自动进行的。首先利用接口struct hostent *gethostbyname(const char *name)将需要解析的域名名称作为参数传入到函数中,然后函数执行后返回一个结构体hostent,其中包括了域名所对应的ip地址列表信息。具体代码如下:
char* dns_decode(char host[])
{
struct hostent* ht=NULL;
struct in_addr* tmp;
char *dns[20];
int i=0;
if((ht=gethostbyname(host))==NULL)
{
herror("gethostbyname wrong!\n");
return NULL;
}
else
{
printf("get the host:%s\n",host);
while(tmp=(struct in_addr*)*ht->h_addr_list)
{
dns[i]=(char *)inet_ntoa(*tmp);
printf("IP:%s\n",dns[i]);
i++;
// printf("IP:%s\n",inet_ntoa(*tmp));
ht->h_addr_list++;
}
}
return dns[0];
}
3.1.2 Socket连接
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。下图是socket建立连接的流程图:
图3.1 socket建立连接流程图
服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept 阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。本模块实现的是客户端,首先初始化好网页所在服务器的ip地址及端口号,然后通过int connect(int sockfd, const struct sockaddr* server_addr, socklen_t addrlen)函数连接到服务器端,为之后发送HTTP请求头做准备。具体代码如下:
int open_socket(struct in_addr server_ip)
{
int client_sock;
struct sockaddr_in server_addr;
client_sock=socket(AF_INET,SOCK_STREAM,0);
if(client_sock<0)
{
printf("socket error\n");
return -1;
}