当前位置:文档之家› 网络爬虫论文

网络爬虫论文

网络爬虫论文
网络爬虫论文

摘要

网络爬虫(Web Crawler),通常被称为爬虫,是搜索引擎的重要组成部分。随着信息技术的飞速进步,作为搜索引擎的一个组成部分——网络爬虫,一直是研究的热点,它的好坏会直接决定搜索引擎的未来。目前,网络爬虫的研究包括Web搜索策略研究的研究和网络分析的算法,两个方向,其中在Web爬虫网络搜索主题是一个研究方向,根据一些网站的分析算法,过滤不相关的链接,连接到合格的网页,并放置在一个队列被抓取。

把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛。网络蜘蛛是通过网页的链接地址来寻找网页,从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。如果把整个互联网当成一个网站,那么网络爬虫就可以用这个原理把互联网上所有的网页都抓取下来。

关键词:网络爬虫;Linux Socket;C/C++;多线程;互斥锁

I

Abstract

Web Crawler, usually called Crawler for short, is an important part of search engine. With the high-speed development of information, Web Crawler-- the search engine can not lack of-- which is a hot research topic those years. The quality of a search engine is mostly depended on the quality of a Web Crawler. Nowadays, the direction of researching Web Crawler mainly divides into two parts: one is the searching strategy to web pages; the other is the algorithm of analysis URLs. Among them, the research of Topic-Focused Web Crawler is the trend. It uses some webpage analysis strategy to filter topic-less URLs and add fit URLs into URL-WAIT queue.

The metaphor of a spider web internet, then Spider spider is crawling around on the Internet. Web spider through web link address to find pages, starting from a one page website (usually home), read the contents of the page, find the address of the other links on the page, and then look for the next Web page addresses through these links, so has been the cycle continues, until all the pages of this site are crawled exhausted. If the entire Internet as a site, then you can use this Web crawler principle all the pages on the Internet are crawling down..

Keywords:Web crawler;Linux Socket;C/C++; Multithreading;Mutex

II

目录

摘要............................................................................ I 第一章概述. (1)

1.1 课题背景 (1)

1.2 网络爬虫的历史和分类 (1)

1.2.1 网络爬虫的历史 (1)

1.2.2 网络爬虫的分类 (2)

1.3 网络爬虫的发展趋势 (3)

1.4 系统开发的必要性 (3)

1.5 本文的组织结构 (3)

第二章相关技术和工具综述 (5)

2.1 网络爬虫的定义 (5)

2.2 网页搜索策略介绍 (5)

2.2.1 广度优先搜索策略 (5)

2.3 相关工具介绍 (6)

2.3.1 操作系统 (6)

2.3.2 软件配置 (6)

第三章网络爬虫模型的分析和概要设计 (8)

3.1 网络爬虫的模型分析 (8)

3.2 网络爬虫的搜索策略 (8)

3.3 网络爬虫的概要设计 (10)

第四章网络爬虫模型的设计与实现 (12)

4.1 网络爬虫的总体设计 (12)

4.2 网络爬虫的具体设计 (12)

4.2.1 URL类设计及标准化URL (12)

4.2.2 爬取网页 (13)

4.2.3 网页分析 (14)

4.2.4 网页存储 (14)

4.2.5 Linux socket通信 (16)

4.2.6 EPOLL模型及其使用 (20)

4.2.7 POSIX多线程及其使用 (22)

第五章程序运行及结果分析 (25)

5.1 Makefile及编译 (25)

5.2 运行及结果分析 (26)

III

第六章总结与展望 (30)

致谢 (31)

参考文献 (32)

IV

第一章概述

第一章概述

1.1 课题背景

网络爬虫,是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁,自动索引,模拟程序或者蠕虫。

网络检索功能起于互联网内容爆炸性发展所带来的对内容检索的需求。搜索引擎不断的发展,人们的需求也在不断的提高,网络信息搜索已经成为人们每天都要进行的内容.如何使搜索引擎能时刻满足人们的需求。最初的检索功能通过索引站的方式实现,而有了网络机器人,即网络爬虫这个技术之后,搜索引擎的时代便开始一发不可收拾了。

1.2 网络爬虫的历史和分类

1.2.1 网络爬虫的历史

在互联网发展初期,网站相对较少,信息查找比较容易。然而伴随互联网爆炸性的发展,普通网络用户想找到所需的资料简直如同大海捞针,这时为满足大众信息检索需求的专业搜索网站便应运而生了。

现代意义上的搜索引擎的祖先,是1990年由蒙特利尔大学学生Alan Emtage发明的Archie。虽然当时World Wide Web还未出现,但网络中文件传输还是相当频繁的,而且由于大量的文件散布在各个分散的FTP主机中,查询起来非常不便,因此Alan Archie工作原理与现在的搜索引擎已经很接近,它依靠脚本程序自动搜索网上的文件,然后对有关信息进行索引,供使用者以一定的表达式查询。由于Archie深受用户欢迎,受其启发,美国内华达System Computing Services大学于1993年开发了另一个与之非常相似的搜索工具,不过此时的搜索工具除了索引文件外,已能检索网页。

当时,“机器人”一词在编程者中十分流行。电脑“机器人”(Computer Robot)是指

某个能以人类无法达到的速度不间断地执行某项任务的软件程序。由于专门用于检索信息的“机器人”程序象蜘蛛一样在网络间爬来爬去,因此,搜索引擎的“机器人”程序就被称为“蜘蛛”程序。世界上第一个用于监测互联网发展规模的“机器人”程序是Matthew Gray开发的World wide Web Wanderer。刚开始它只用来统计互联网上的服务器数量,后来则发展为能够检索网站域名。与Wanderer相对应,Martin Koster于1993年10月创建了ALIWEB,它是Archie的HTTP版本。ALIWEB不使用“机器人”程序,而是靠

1

广东石油化工学院本科毕业(设计)论文: Linux平台下C/C++网络爬虫的设计与实现

网站主动提交信息来建立自己的链接索引,类似于现在我们熟知的Yahoo。

随着互联网的迅速发展,使得检索所有新出现的网页变得越来越困难,因此,在Matthew Gray的Wanderer基础上,一些编程者将传统的“蜘蛛”程序工作原理作了些改进。其设想是,既然所有网页都可能有连向其他网站的链接,那么从跟踪一个网站的链接开始,就有可能检索整个互联网。到1993年底,一些基于此原理的搜索引擎开始纷纷涌现,其中以Jump Station、The World Wide Web Worm(GoTo的前身,也就是今天Overture),和Repository-Based Software Engineering (RBSE) spider最负盛名。

然而Jump Station和WWW Worm只是以搜索工具在数据库中找到匹配信息的先后次序排列搜索结果,因此毫无信息关联度可言。而RBSE是第一个在搜索结果排列中引入关键字串匹配程度概念的引擎最早现代意义上的搜索引擎出现于1994年7月。当时Michael Mauldin将John Leavitt的蜘蛛程序接入到其索引程序中,创建了大家现在熟知的Lycos。同年4月,斯坦福(Stanford)大学的两名博士生,David File和美籍华人杨致远(Gerry Yang)共同创办了超级目录索引Yahoo,并成功地使搜索引擎的概念深入人心。从此搜索引擎进入了高速发展时期。目前,互联网上有名有姓的搜索引擎已达数百家,其检索的信息量也与从前不可同日而语。比如最近风头正劲的Google,其数据库中存放的网页已达30亿之巨。

随着互联网规模的急剧膨胀,一家搜索引擎光靠自己单打独斗已无法适应目前的市场状况,因此现在搜索引擎之间开始出现了分工协作,并有了专业的搜索引擎技术和搜索数据库服务提供商。像国外Inktomi,它本身并不是直接面向用户的搜索引擎,但向包括Overture(原GoTo)、LookSmart、MSN、HotBot等在内的其他搜索引擎提供全文网页搜索服务。国内的百度也属于这一类(注),搜狐和新浪用的就是它的技术。因此从这个意义上说,它们是搜索引擎的搜索引擎。

1.2.2 网络爬虫的分类

网络爬虫种类繁多,如果按照部署在哪里分,可以分成:

(1)服务器侧:一般是一个多线程程序,同时下载多个目标HTML,可以用PHP,Java, Python等做,一般综合搜索引擎的爬虫这样做。但是,如果对方讨厌爬虫,很可能封掉服务器的IP,服务器IP又不容易改,另外耗用的带宽也是较贵。

(2)客户端:很适合部署定题爬虫,或者叫聚焦爬虫。做一个与Google,百度等竞争的综合搜索引擎成功的机会微乎其微,而垂直搜索或者比价服务或者推荐引擎,机会要多得多,这类爬虫不是什么页面都取的,而是只取关心的页面,而且只取页面上关心的内容,例如提取黄页信息,商品价格信息,还有提取竞争对手广告信息的。这类爬虫可以部署很多,而且可以很有侵略性。可以低成本大量部署,由于客户端IP地址是动态的,所以很难被目标网站封锁。

2

第一章概述

1.3 网络爬虫的发展趋势

目前,大多数的搜索引擎都是基于关键词的搜索引擎。基于关键字匹配的搜索技术有较大的局限性:首先,它不能区分同形异义。其次,不能联想到关键字的同义词。

Web商业化至今,搜索引擎始终保持着网络上被使用最多的服务项目的地位,然而,随着网上内容的爆炸式增长和内容形式花样的不断翻新,搜索引擎越来越不能满足挑剔的网民们的各种信息需求。

搜索引擎的发展面临着两大难题:一是如何跟上Internet的发展速度,二是如何为用户提供更精确的查询结果。所以,传统的引擎不能适应信息技术的高速发展,新一代智能搜索引擎作为一种高效搜索引擎技术的在当今的网络信息时代日益引起业界人士的关注。搜索引擎己成为一个新的研究、开发领域。因为它要用到信息检索、人工智能、计算机网络、分布式处理、数据库、数据挖掘、数字图书馆、自然语言处理等多领域的理论和技术,所以具有综合性和挑战性。又由于搜索引擎有大量的用户,有很好的经济价值,所以引起了世界各国计算机科学界和信息产业界的高度关注,目前的研究、开发十分活跃,并出现了很多值得注意的动向。

1.4 系统开发的必要性

爬虫程序是一个自动获取网页的程序。它为搜索引擎从互联网上下载网页,是搜索引擎的重要组成部分。爬虫程序的实现策略,运行效率直接影响搜索引擎的搜索结果。不同的搜索引擎,会根据对搜索结果的不同需求,选择最合适的爬行策略来搜集互联网上的信息。高效,优秀的爬虫程序可以使人们在互联网上寻找到更及时,更准确的信息。而现在Linux平台下开源的搜索引擎资料较少,作为实现最终开发目标搜索引擎的一部分,本爬虫程序可以为搜索引擎提供良好的网页获取能力,并可以为在Linux下开发网络爬虫的后来者提供参考。

1.5 本文的组织结构

本文主要根据网络爬虫的特点,结合搜索引擎关键技术,linux网络编程,对爬虫程序的关键技术做了详细的分析和研究。然后设计并实现了一个以抓取相关关键字内容并实现离线浏览功能的网络爬虫系统。

本文主要分为6个章节,结构安排如下:

(1)绪论,对课题的背景研究意义和爬虫的研究现状做了简单介绍。

3

广东石油化工学院本科毕业(设计)论文: Linux平台下C/C++网络爬虫的设计与实现

(2)相关技术和工具介绍。对网络爬虫的定义、评价指标分类、工作原理并对开发环境和工具进行了简单介绍。并以此引出网络爬虫系统的相关知识介绍。

(3)网络爬虫的模型分析。对网络爬虫视线中的主要思想以及关键技术进行了具体的分析。

(4)网络爬虫的模型设计根据第三章内容。对爬虫系统进行了详细设计,并对本爬虫系统的模型实现进行具体分析。同时也对使用的技术进行简单的介绍。

(5)程序运行和结果分析对程序的编译运行进行简单介绍。并对测试结果进行了简单分析。

(6)总结和展望。

4

第二章相关技术和工具综述

第二章相关技术和工具综述

2.1 网络爬虫的定义

定义1:网络爬虫是一个自动提取网页的程序,它为搜索引擎从Web上下载网页,是搜索引擎的重要组成部分。通用网络爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL列表;在抓取网页的过程中,不断从当前页面上抽取新的URL放入待爬行队列,直到满足系统的停止条件。

定义2:网络爬虫就是根据一定的网页分析算法过滤与主题无关的链接,保留相关的链接并将其放入待抓取的URL队列中;然后根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。所有被网络爬虫抓取的网页将会被系统存储,进行一定的分析、过滤,并建立索引,对于网络爬虫来说,这一过程所得到的分析结果还可能对后续的抓取过程进行反馈和指导。

定义3:如果网页p中包含超链接l,则p称为链接l的父网页。

定义4:如果超链接l指向网页t,则网页t称为子网页,又称为目标网页。网络爬虫的基本思路就是按照事先给出的主题,分超链接和已经下载的网页内容,预测下一个待抓取的URL及当前网页的相关度,保证尽可能多地爬行、下载相关的网页,尽可能少地下载无关网页。

2.2 网页搜索策略介绍

网页的抓取策略可以分为深度优先、广度优先和最佳优先三种。深度优先在很多情况下会导致爬虫的陷入(trapped)问题,目前常见的是广度优先和最佳优先方法。2.2.1 广度优先搜索策略

广度优先搜索策略是指在抓取过程中,在完成当前层次的搜索后,才进行下一层次的搜索。该算法的设计和实现相对简单。在目前为覆盖尽可能多的网页,一般使用广度优先搜索方法。也有很多研究将广度优先搜索策略应用于聚焦爬虫中。其基本思想是认为与初始URL在一定链接距离内的网页具有主题相关性的概率很大。另外一种方法是将广度优先搜索与网页过滤技术结合使用,先用广度优先策略抓取网页,再将其中无关的网页过滤掉。这些方法的缺点在于,随着抓取网页的增多,大量的无关网页将被下载并过滤,算法的效率将变低。

5

广东石油化工学院本科毕业(设计)论文: Linux平台下C/C++网络爬虫的设计与实现

2.3 相关工具介绍

2.3.1 操作系统

本网络爬虫程序开发环境为Linux CentOS操作系统,并且目标是在Linux下运行,而在其他平台上会出现各种无法正常运行的问题,所以在此有必要介绍一下该程序的运行环境,Linux操作系统。

Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX 的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

而Linux主要作为Linux发布版(通常被称为"distro")的一部分而使用。Linux发布版指的就是通常所说的“Linux操作系统”,它可能是由一个组织,公司或者个人发布的。通常来讲,一个Linux发布版包括Linux内核,将整个软件安装到计算机上的一套安装工具,各种GNU软件,其他的一些自由软件,在一些特定的Linux发布版中也有一些专有软件。发布版为许多不同的目的而制作,包括对不同计算机硬件结构的支持,对一个具体区域或语言的本地化,实时应用,和嵌入式系统。目前,超过三百个发布版被积极的开发,最普遍被使用的发布版有大约十二个。较为知名的有Fedora,Ubuntu,Mageia,红旗Linux,CentOS等。本程序所使用的开发操作系统是Linux中比较知名的CentOS。

2.3.2 软件配置

在CentOS Linux中,本文主要用的开发软件是Vim。一般Linux的发行版都自带Vim,Vim是个可配置性极强的文本编辑器,可以进行高效的文本编辑。

Vim常被称作“程序员的编辑器”,其功能如此强大以致许多人认为它就是个完整的IDE。当然,它并不仅仅为程序员而生。面对各种文本编辑,无论是撰写email还是编辑配置文件,Vim都臻于完美。但是只有你自己配置之后才能变成适合于你自己的开发工具。

所以需要修改Vim的配置文件,常用的有(以下为简单配置):

“不要使用vi的键盘模式,而是vim自己的:

set nocompatible

history文件中需要记录的行数:

set history=100

“语法高亮:

syntax on

“为C程序提供自动缩进:

6

第二章相关技术和工具综述

set smartindent

“使用C样式的缩进:

set cindent

“制表符为4:

set tabstop=4

“统一缩进为4:

set softtabstop=4 set shiftwidth=4

还有一点不能忽视,那就是安装GCC编译器,因为本文写的所有代码都是C/C++格式的。虽说基本上每个发行版都已经安装了GCC编译器,但不是很全,为了以防万一,在终端下执行了以下命令:

$ yum –y install gcc

$ yum –y install gcc-c++

$ yum install make

--或者执行

$ yum groupinstall “Development Tools”

--或者执行

$ yum install gcc gcc-c++ kernel -devel

GCC下编译.c文件:gcc –o xx xx.c,编译.cpp文件只需把gcc改为g++即可。

在多文件编译的情况下,这样的命令会很繁琐,通常会写一个或多个Makefile文件来解决这个问题,在本文的最后会讲到。

7

广东石油化工学院本科毕业(设计)论文: Linux 平台下C/C++网络爬虫的设计与实现

8

第三章 网络爬虫模型的分析和概要设计

3.1 网络爬虫的模型分析

网络爬虫框架参考的是一个叫larbin 的开源爬虫,它是由法国的年轻人Sebastien Ailleret 独立开发,用C++语言实现,其代码可以直接在网上可以下载到。以下是本程序爬虫使用的框架,看起来更像是主题爬虫的框架。如图3.1所示。

QUEUE_URL

Push

QUEUE_URL 为空/其

它终止条件

Pop

退出

Yes 抓取指定网页No

网页分析提取URL

Analyze

Yes

Store 初始URL

存储Html

符合条件(不重复/包含关键字)

丢弃

No

图 3-1 网络爬虫的基本框架图

首先建立URL 任务列表队列,即开始要爬取的URL 。由URL 任务列表开始,根据预先设定的深度爬取网页,同时判断URL 是否重复,按照一定算法和排序方式搜索页面,然后对页面按照一定算法进行分析,并提取相关URL ,最后将所得URL 返回任务列表队列。之后将任务列表中URL 重新开始爬取,从而使网络爬虫进行循环工作。

3.2 网络爬虫的搜索策略

第三章 网络爬虫模型的分析和概要设计

9

本文的搜索策略为广度优先搜索策略。如下图3-2所示。搜索

过程为abcdefghijklmnop 这样一个顺序。

图3-2 广度优先搜索策略示意图

(1)定义一个状态结点

采用广度优先搜索算法解答问题时,需要构造一个表明状态特征和不同状态之间关系的数据结构,这种数据结构称为结点。不同的问题需要用不同的数据结构描述。

(2)确定结点的扩展规则

根据问题所给定的条件,从一个结点出发,可以生成一个或多个新的结点,这个过程通常称为扩展。结点之间的关系一般可以表示成一棵树,它被称为解答树。搜索算法的搜索过程实际上就是根据初始条件和扩展规则构造一棵解答树并寻找符合目标状态的结点的过程。

广度优先搜索算法中,解答树上结点的扩展是沿结点深度的“断层”进行,也就是说,结点的扩展是按它们接近起始结点的程度依次进行的。首先生成第一层结点,同时检查目标结点是否在所生成的结点中,如果不在,则将所有的第一层结点逐一扩展,得到第二层结点,并检查第二层结点是否包含目标结点…… 对长度为n+1的任一结点进行扩展之前,必须先考虑长度为n 的结点的每种可能的状态。因此,对于同一层结点来说,求解问题的价值是相同的,我们可以按任意顺序来扩展它们。这里采用的原则是先生成的结点先扩展。

结点的扩展规则也就是如何从现有的结点生成新结点。对不同的问题,结点的扩展规则也不相同,需要按照问题的要求确定。

(3)搜索策略

为了便于进行搜索,要设置一个表存储所有的结点。因为在广度优先搜索算法中,要满足先生成的结点先扩展的原则,所以存储结点的表一般设计成队列的数据结构。

搜索的步骤一般是:

(1)从队列头取出一个结点,检查它按照扩展规则是否能够扩展,如果能则产生一个新结点。

广东石油化工学院本科毕业(设计)论文: Linux 平台下C/C++网络爬虫的设计与实现

10

(2)检查新生成的结点,看它是否已在队列中存在,如果新结点已经在队列中出现过,就放弃这个结点,然后回到第(1)步。否则,如果新结点未曾在队列中出现过,则将它加入到队列尾。

(3)检查新结点是否目标结点。如果新结点是目标结点,则搜索成功,程序结束;若新结点不是目标结点,则回到第(1)步,再从队列头取出结点进行扩展。

最终可能产生两种结果:找到目标结点,或扩展完所有结点而没有找到目标结点。

3.3 网络爬虫的概要设计

本网络爬虫的开发目的,通过网络爬虫技术一个自动提取网页的程序,实现搜索引擎从自己想要访问的网上下载网页,再根据已下载的网页上继续访问其它的网页,并将其下载直到满足用户的需求。

根据现实中不同用户的实际上的各种需求,本项目简单实现主题爬虫,本网络爬虫

需要达到如下几个目标:

(1)设计基于多线程的网络爬虫,客户端向服务器发送自己设定好请求。如图3-3所示。

图3-3 多线程网络爬虫概要设计图模型

(2)通过 http 将Web 服务器上协议站点的网页代码提取出来。 (3)根据一定的正则表达式提取出客户端所需要的信息。

(4)广度优先搜索可从网页中某个链接出发,访问该链接网页上的所有链接,访问完成后,再通过递归算法实现下一层的访问。

本网络爬虫最终将设计成一个能够自动读写配置文件并且在后台自动执行的网络

第三章 网络爬虫模型的分析和概要设计

爬虫程序。网络爬虫工作流程图如图3-4所示。

开始

从配置文件中读取初始

URL 作为源URL

获取网页

以正则表达式过滤网页标签提取目标URL

满足条件停止

结束

根据宽度有限算法搜索目标URL 网络蜘蛛循环爬

图3-4 网络爬虫工作流程图

广东石油化工学院本科毕业(设计)论文: Linux平台下C/C++网络爬虫的设计与实现

第四章网络爬虫模型的设计与实现

4.1 网络爬虫的总体设计

根据本网络爬虫的概要设计本网络爬虫是一个自动提取网页的程序,根据设定的主题判断是否与主题相关,再根据已下载的网页上继续访问其它的网页,并将其下载直到满足用户的需求。

(1)设计基于多线程的网络爬虫。

(2)通过http协议将待爬取URL列表对应的URL的网页代码提取出来。

(3)提取出所需要的信息并且通过算法判断网页是否和设定的主题相关。

(4)广度优先搜索,从网页中某个链接出发,访问该链接网页上的所有链接,访问完成后,再通过递归算法实现下一层的访问,重复以上步骤。

总的来说爬虫程序根据输入获得URL任务列表,即初始URL种子,把初始种子保存在临界区中,按照广度搜索运算法搜索抓取网页并提取URL返回到临界区中,通过判断主题相关度算法判断相关度,取出不相关网页,从而使整个爬虫程序循环运行下去。

4.2 网络爬虫的具体设计

4.2.1 URL类设计及标准化URL

URL 的一般形式是:://<主机>:<端口>/<路径>。为了方便处理,设计了一个名叫URL的类,它包含Host(主机名),Port(端口),File(文件路径),Fname(给这张网页取的名字)。以下代码是class URL的成员及其成员函数(摘自web.h):

class URL

{

public:

URL() {}

void SetHost(const string& host) { Host = host; }

string GetHost() { return Host; }

void SetPort(int port) { Port = port; }

int GetPort() { return Port; }

void SetFile(const string& file) { File = file; }

12

第四章网络爬虫模型的设计与实现

string GetFile() { return File; }

void SetFname(const string& fname) { Fname = fname; }

string GetFname() { return Fname; }

~URL() {}

private:

string Host;

int Port;

string File;

string Fname;

};

对URL的处理:

此外,注意到在网页源代码中,URL有些是绝对路径,有些是相对路径,还有一些URL中存在字符‘#’,多个‘///’等等。

因此,需要对这些URL进行处理,分别得到每个URL的Host,Port,File。以下是本文对URL的设定:

(1)URL的File成员不能以‘/’结尾,若有则以‘\0’填充;若该File成员没有路径,则设定其路径为‘/’。这样做的目的是为了便于URL排重。

(2)URL的File成员中若有‘#’字符,则删除它及它以后的字符,剩余的字符串作为File的值。

(3)若URL中没有显式表明端口,则默认Port成员的值为80。

(4)若URL没有主机属性,则默认Host成员的值为初始URL的主机名。

4.2.2 爬取网页

在分析网页之前,首先网页需要被抓取下来,分析一下数据从服务器保存到本地的过程。

第一部分:分析之前,首先要明确的是:当从sockfd读取数据时,最前面一部分是和网页本身无关的信息,比如有些网页未找到,就会返回404 not found等服务信息,类似的,每种情况会返回对应的信息,因此,对于一些服务信息,应该不予记录。当读到‘>’字符时才开始正式记录网页内容。

第二部分:定义一个tmp的字符数组,用来临时存放抓取的的网页,抓取方法与第一部分相同同,都是用read函数,不同的是这里是一块一块抓取,效率上能比每次抓取一个字节要高。有人可能会问,为什么不直接存放到文件中,而要保存到临时数组中呢?解释是:因为下一步分析网页时,有个URL重定向的过程,程序还会继续修改tmp 数组。如果直接保存到文件,那么还得再次打开文件分析网页,这样会降低效率,因为在磁盘执行读写操作总是比在内存读写慢得多。

13

广东石油化工学院本科毕业(设计)论文: Linux平台下C/C++网络爬虫的设计与实现

4.2.3 网页分析

(1)URL提取

考虑到网页中的链接格式主要是:title,因此本文通过string自身封装的find函数来找到每一个”herf”的位置,接下来的情况稍微有些复杂,分为三种情况。第一种:URL用双引号引起来;第二种:以单引号引起来;第三种:URL没有被引起来。在此使用了一个标记变量(flag)来区分以上三种情况。

(2)URL的重定向

考虑到本文的要求不仅仅是抓取网页本身,还要实现一个离线浏览网页的功能,原有的链接不再有效,因此,URL的重定向这一步不可缺少。

之前,爬虫已经抓取了一些网页并存放在了一个名为Pages的文件夹中,而且其中的每个网页都进行了重命名处理(本文直接以url.Fname的字符串哈希值作文保存网页的文件名)。那么在本地的URL无论在路径和文件名上都和原来网页上的链接都是不对应的,要想实现和原来一样的网页跳转,必须修改每个链接的herf值。

对于原来的链接title,假设现在重命名该网页为new.html,那么如何处理怎么才能转化成新的链接呢?方法有很多,比如可以通过覆盖和移动,使得两个引号直接的内容为new.html。本文采用的方法如下:

现已知第一个引号的位置为pos_1,因此可以调用string类的insert方法。调用后的效果如下:

title

这样处理不仅屏蔽了”xxx.html”,也避免了删除原有链接等不必要操作,一定程度上提高了代码的效率。

(3)URL判重

抓取网页时有一个非常棘手的问题,那就是重复抓取问题。大家知道,一个网站中的链接非常多,抽象出来就是一个巨大的蜘蛛网,类似与图论中的无向图。如果不对爬虫进行设置,它就像一只无头苍蝇一样,到处乱撞。这样待抓取队列里的URL越来越多,并且好多都是重复的。那么如何才能跳出这个怪圈呢?C++已经为大家提供了一个叫set的容器(当然也可以使用hash来判重)。

在cplusplus这样介绍:set是一种存放唯一性元素的关联容器,它里面的每一个元素都称为关键字,它由二叉搜索树实现。

由于它的唯一性,高效性,把它选择作为URL判重的一种类似hash的工具。本文代码如下:

定义:setSet;

使用:Set.insert(hashVal);

4.2.4 网页存储

14

第四章网络爬虫模型的设计与实现

前面爬虫已经抓取到了一张网页,并且进行了重定向处理。那么接下来要做的事就是把它保存到磁盘里,在这一步需要用到文件操作(摘自http.cpp)。

chdir("Pages");

int fd = open(url_t.GetFname().c_str(), O_CREAT|O_EXCL|O_RDWR, 00770);

/* check whether needs re-fetch */

if(fd < 0) {

if(errno == EEXIST) {

stat(url_t.GetFname().c_str(), &buf);

int len = buf.st_size;

if(len >= flen) goto NEXT;

else {

fd = open(url_t.GetFname().c_str(), O_RDWR|O_TRUNC, 00770);

if(fd < 0) {

perror("file open error");

goto NEXT;

}

}

}

else {

perror("file open error");

goto NEXT;

}

}

write(fd, HtmFile.c_str(), HtmFile.length());

NEXT:

close(fd);

// todo next

以上代码主要功能是保存已抓取网页的内容到磁盘。有时候在网络状况不理想的情况下,爬虫抓取有些网页时会导致请求超时,或抓取内容不全,因此为了完善抓取内容,可以进行下一次重复抓取,其抓取条件为:

该文件不存在,则直接进行抓取;该文件已经存在且当前抓取的内容多与上次抓取的,则覆盖上次保存的文件;其它情况,放弃。

第一行代码使用O_CREAT | O_EXCL | O_RDWR模式打开,当该文件已经存在时返回-1,错误代码存放在error中,错误代号为EEXIST。

15

广东石油化工学院本科毕业(设计)论文: Linux 平台下C/C++网络爬虫的设计与实现

16

代码中使用stat 函数来读取参数为文件名的文件信息,其中我们需要的就是st_size 这个成员的内容,它以字节形式记录了文件的大小。这样就可以与当前抓取网页大小(存放于变量flen 中)比较,从而判断是否需要覆盖原有文件。

本文以上代码虽然使用了不推荐的goto 语句,因为程序需要跳过write 函数。不过使用goto 语句在没有给程序带来混乱的情况下实现了一条break 语句实现不了的功能,因此更具实用性。

4.2.5 Linux socket 通信

本文中的socket 通信基于TCP ,因此有必要提一下TCP 的连接和断开过程。TCP 的可靠连接得益于它的三次握手原理,下图形象的表示了TCP 三次握手建立连接和两次半关闭断开连接的具体过程。在连接和断开连接之间,客户端和服务器即可进行双向的信息通信。

客户端

服务器

Socke Connect (阻塞)(主动打开)SYN J SYN K ,ACK

J+1Socket,bind,liste

n

(被动打开)Accept (阻塞)

ACK K+1

Connect 返

Accept 返回Read(阻塞)

Close (主动关闭)

FIN M (被动关闭)Read 返回0Close

ACK M+1

FIN N

ACK N+1

图4-1 TCP 三次握手与两次半关闭过程

在了解各个Socket 函数之前,首先来看一个经典的流程图,几乎每次网络通信都需要走以下流程,它详细地显示了TCP 客户端和TCP 服务器之间的Socket 通信流程:

相关主题
文本预览
相关文档 最新文档