基于网络蜘蛛的ACM自动刷题系统设计与实现DOC.docx
《基于网络蜘蛛的ACM自动刷题系统设计与实现DOC.docx》由会员分享,可在线阅读,更多相关《基于网络蜘蛛的ACM自动刷题系统设计与实现DOC.docx(29页珍藏版)》请在冰豆网上搜索。
基于网络蜘蛛的ACM自动刷题系统设计与实现DOC
基于网络蜘蛛的ACM自动刷题系统设计与实现
摘要
互联网的发展日新月异,编程的门槛也越来越低,高薪吸引着众多人加入到IT行业。
这也使得越来越多的编程初学者需要强化自己的编程思维,他们可以通过在各个高校ACM平台上练习来提高自己的编程能力。
在没有老师、同学的帮助下,如何帮助初学者解决难度较高的题目,是一个值得研究的问题。
利用网络蜘蛛的技术为此类问题提供一个有效可行的途径,将它与ACM刷题结合起来,能更好地帮助初学者解决类似的问题。
本课题主要研究的主要内容包括:
网页文本的自动抓取、答案文本的预处理、自动刷题器的实现。
分析了网页文本的特点和目标代码转换的关键技术,实现了基于网络蜘蛛的ACM自动刷题系统的总体设计及各个功能模块。
主要的功能模块分别为:
网络蜘蛛、文本内容过滤、目标代码转换、自动刷题器。
首先分析了网络蜘蛛的遍历策略及.NET自带的网页解析器、答案文本预处理中文本过滤器与目标代码转换,在此基础上实现了自动刷题器,再使各个功能模块协调实现了自动刷题系统。
关键词:
网络蜘蛛ACM文本过滤自动刷题
1引言
随着互联网的高速发展,编程的门槛也越来越低,高薪吸引着众多人加入到IT行业。
这也使得越来越多的编程初学者需要强化自己的编程思维,可以通过在各个高校ACM平台上练习来提高自己的编程能力。
而对于初学者来说,难度较高的题目也无法独立解决,需要自己借助网络平台、同学、老师求助等来解决这类难题。
为了更好的帮助这些初学者,可以利用网络蜘蛛的技术,将它与ACM刷题结合起来,能更好地帮助初学者解决类似的问题。
1.1研究的意义
互联网上资源与日俱增,如何在众多的资源当中快速有效地获取相关的资源
并利用是我们研究的热点,基于网络蜘蛛技术为此类问题提供了一个切实可行的途径。
同样也可以利用网络蜘蛛技术完成ACM自动刷题,来帮助编程初学者提高编程能力,他们也不再需要去XX搜索题目资料,这也就简化他们刷题过程,提高编程效率,也为他们提供解决编程过程中遇到问题一种新的方式。
1.2本课题研究的主要内容
本文分析了在目前编程初学者存在的主要问题的基础上,提出一种基于网络蜘蛛技术ACM自动刷题解决方案,它能有效地帮助编程初学者,大大降低初学者手动搜索答案筛选的工作量。
基于网络蜘蛛技术的自动刷题涉及到网页文本的自动抓取、网页文本的预处理、网页文本的自动刷题器等。
该系统不仅可完成网页文本的自动刷题的能力,也可以用于信息搜索的优化,实现网络上资源的获取并选择利用。
1.2.1网页文本的自动抓取
网络蜘蛛(即WebSpider)是目前搜索引擎从互联网上抓取目标WEB网页的广泛使用的工具。
庞大的互联网如同一个巨大的蜘蛛网络,那么Spider就是在互联网上的蜘蛛。
通过网络蜘蛛访问网页,抓取网页文本内容,然后对抓取的网页文本内容进行文本解析,从中提取用于自动刷题器的文本内容。
网络蜘蛛是通过上一个网页中的URL来寻找下一个网页。
一般地,从该网站的首页开始,获取该网站首页的内容,找到在该网页中的链向其他网页的链接,然后通过这些链接去寻找下一个网页,以此类推,直到该网站的所有链接都被遍历过为止。
网络蜘蛛对网页抓取分析,提取出网页文本中的某些关键信息或链向到其它网页的URL地址。
1.2.2答案文本的预处理
答案文本预处理包括文本内容过滤和目标代码(即查找的题目所对应答案文本)转换两个子模块。
文本内容过滤是对网页文本进一步过滤,从中提取用于目标代码的文本内容。
目标代码转换是把经过过滤后的文本内容转换成可编译代码,其中的主要问题是HTML文件处理和目标代码中特殊字符的转换。
HTML文件当中的字符实体是为了在HTML中显示特殊的字符,而可编译代码不同于字符实体,可编译代码通过ASCII码来显示特殊字符,因此需要进行转换。
可编译代码的ASCII码与特殊字符一一对应,而HTML中通过实体与特殊字符一一对应。
这就使得网页文本的预处理变得复杂。
1.2.3自动刷题器的实现
自动刷题器包括:
用户自动登录、答案文本自动搜索、源代码自动提交、刷题状态自动判断,但如何使各个功能模块自动化处理协调是本系统的硬性标准。
目前,用户自动登录都是通过预先在数据库中保存账号实现的,本系统是否可以采用其他方式实现自动登录也是值得思考的。
答案文本自动搜索可以通过常用的XX搜索引擎实现,但如何结合网络蜘蛛技术实现自动搜索功能也是需要多加思考。
自动刷题状态判断这一部分可以采用与大多数系统一样,通过程序判断即可,但程序判断结果如何处理也是尽量做到智能化。
自动刷题器的实现也就能大大降低编程初学者手动搜索的工作量了。
因此,自动刷题器的实现及其关键技术是本课题研究的重点之一。
2总体设计
在这部分主要介绍本课题总体设计的各功能模块,选取合理的开发平台和开发语言。
2.1功能模块
基于网络蜘蛛的ACM自动刷题系统主要由网络蜘蛛、网页文本内容过滤器、目标代码转换、自动刷题器等模块组成。
总体结构功能模块图如图2-1所示。
图2-1功能模块图
2.1.1网络蜘蛛
网络蜘蛛的功能是从互联网获取网页页面的内容。
它能够根据权限获取站点的全部或部分网页文本资源。
通过网络蜘蛛技术可以实现答案文本的自动搜索,只要预先设定一个URL给网络蜘蛛,它可以抓取该网页中的链接到其他网页的URL。
这也就类似于,在XX搜索引擎下,输入关键字,查找关键字信息。
因此,利用网络蜘蛛技术是可以实现答案文本的自动搜索。
2.1.2网页文本过滤器
网页文本过滤器主要是将网页中与答案文本无关的内容过滤掉。
诸如:
网页中的多媒体信息、文档信息、HTML文件信息过滤掉,提取出所需的答案文本和子链接,将子链接保存下来。
2.1.3目标代码转换
目标代码转换的功能是将文本内容过滤出的目标代码转换成可编译代码。
由于目标代码存在特殊字符,无法通过刷题平台编译系统,因此需要将特殊字符转换成可编译的特殊字符。
2.1.4自动刷题器
自动刷题器功能包括:
用户自动登录模块、答案文本自动搜索模块、源代码自动提交模块、刷题状态自动判断模块。
用户自动登录模块采用类似快捷键的方式实现自动登录的,答案文本自动搜索模块是通过网络蜘蛛技术实现答案文本在XX搜索引擎自动搜索的,源代码自动提交模块与自动登陆模块类似。
刷题状态自动判断是在对答案文本预处理以及文本完成目标代码转换成可编译代码后得到之后再紧接着判断刷题状态。
2.2开发平台选择
开发一个操作简便、功能易于扩充、执行效率满足要求、信息处理灵活、网络交互能强力等特点的自动刷题工具,C#是一个很好的选择。
VisualStudio2015C#是基于Microsoft.NET平台的开发工具,在Microsoft.NET平台下,可以使用该平台提供的一系列的工具和接口来最大程度地开发本系统。
比如:
借助强大的WEB控件组件可以轻松的实现IE浏览器的功能,这与JAVA相比,实现IE浏览器功能就简单不少。
此外,C#的另一个优点在它具有与C++类似的语法,但C++是一种混合式语言,而C#是完全面向对象的。
而且使用C#语言开发出较少bug的代码比用C++要方便得多。
在C#语言中,它具有以下特性来消除开发者经常会出现的bug:
(1)在C++中,它需要开发者自己手动删除动态分配给堆的内存,而在C#中,我们并不需要这么做。
在C#中,采用自带的垃圾回收机制,它能自动在合适的时机回收不再使用的内存,因此不会出现像内存泄漏的情况。
(2)在C++中,会涉及到使用大量的指针,而在C#中,通过类实例的引用,有效避免了指针使用。
而且C#也不再支持指针类型数据,提高了程序安全性,从而使程序更加健壮。
(3)在C#中,C#的对象模型使得面向对象的编程思想有了更好的体现,它使用的是.NET框架的类库。
在.NET框架下,C#开发者拥有了一个逻辑结构一致的程序设计开发环境。
而在C++中,则更依赖于以继承和模板为基础的标准库,使得程序开发者的工作量会加大。
(4)在C#中,C#不再支持多重继承,通过从ObjectC中借鉴而来的接口实现多继承,能代替多继承大部分功能,而且也不需要管理多重继承层次关系。
3网络蜘蛛
网络蜘蛛(Spider)又被称为网络机器人(Robot)或者爬虫(Crawler),它的主要目的是为获取在互联网上的信息。
当我们遇到问题时,第一反应便会想到去使用XX、谷歌等搜索引擎。
正当我们使用这些搜索引擎时一定会有这样的疑惑:
互联网上的丰富的信息资源是如何被搜索引擎检索到的呢?
了解了网络蜘蛛技术之后,显然这些搜索引擎正是运用了网罗蜘蛛技术才能够快速地找到如此之多的相关信息。
广度优先搜索网络蜘蛛基本工作的方式:
首先查看其中一个页面内容,从中提取相关信息和URL链接,然后再访问该网页的所有URL链接提取相关信息和URL,以此类推,直到站点全部被访问完。
显然,网络蜘蛛工作方式就如同一张蜘蛛网,因此它被称为“网络蜘蛛”。
3.1网络蜘蛛的遍历策略
整个互联网事实上是一个庞大的图,当中的每一个URL都类似于图中的一个节点,因此,对于网页遍历也可以采用图的遍历算法进行访问。
一般地,网络蜘蛛的遍历策略有三种:
广度优先、深度优先和最佳优先遍历,这三种遍历策略与图的遍历一一对应。
首先,大多数网络蜘蛛会采用广度优先遍历。
广度优先的网络蜘蛛会优先抓取起始网页中链接的所有网页,然后再选择其中的一个链接网页,继续抓取在此网页中链接的所有网页,一层一层地访问[1]。
这是最常用的方式,使用这个方法可以提高网络蜘蛛抓取速度,因为它可以让网络蜘蛛并行处理。
深度优先遍历是指网络蜘蛛从起始页开始,跟踪每个子链接,访问完这条线路上所有网页之后再访问下一个起始页,继续跟踪子链接,以此类推,直到站点全部被访问完[2]。
这个方法的优点是网络蜘蛛比较容易设计实现。
最佳优先遍历策略又称为“页面选择问题”,为了先抓取重要的网页,可以采用最佳优先遍历策略,通常保证在有限带宽下,做到尽可能访问到重要的网页。
如图3-1所示的一个简单的网站结构拓扑图,使用不同的搜索策略,得到的搜寻路径自然也不同。
图3-1网站结构拓扑图
按照广度优先遍历策略抓取算法,则可能的抓取顺序为:
A,B,C,E,F,G,H,D。
如果按照深度优先遍历策略抓取算法,则可能抓取顺序为:
A,C,G,D,再回溯抓取E,H,再抓取B,最后抓取F。
在图中存在着环路A-C-G-D-A,因此应采用适当的策略避免陷入死循环。
一种可行的方法是:
将所有已经访问过的网站的URL地址存入到URL历史表中,对任何一个未被访问的网站,都应先将其URL地址与URL历史表中进行比较,若是一个新URL地址,则访问该网站,否则,不需要对该网站的访问。
因为我们不可能抓取所有的网页,系统开发者可以在网络蜘蛛中对一些次要的网站设置访问层数的限制,即对于超过一定层数的网页不再抓取。
例如,在3-1图中,假设A为网站起始首页,则A属于0层,B、C、E、F属于第1层,G、H属于第2层,D属于第3层。
如果网络蜘蛛设置的访问限制层数为2的话,网页文本D就不会被访问到,这使得网络蜘蛛只能获取网站上一部分网页文本,另外一部分则不能被获取到。
不过,有统计表明,层数比较浅的网页文本一般多为重要信息,而层数比较深的网页文本一般多为次要信息。
因此这种做法信息的主体部分能被覆盖。
相对于网站开发者来说,扁平化设计网站结构更利于搜索引擎获取更多的相关网页信息,这就能达到网站开发者的预期目的。
另外,网络蜘蛛在访问网页文本内容的时候,可能会遇到一些文档权限和加密数据的问题。
显然,这些内容需要更高权限才能访问。
这些网页内容的所有者可以通过有关协议让网络蜘蛛不能够抓取到相关数据,但有一些网站,希望自己站点的内容能被搜索到,但该内容又不是完全免费的。
例如:
对于一些主要以出售信息为经营方式的网站,他们希望搜索引擎能够搜索到他们的出售信息,但又不能完全免费的提供给搜索者查看,这样就需要提高网络蜘蛛的权限。
比如:
通过提供相应权限的用户名和密码或直接付费。
通过提高网络蜘蛛的权限,可以实现对这些加密网页进行网页内容抓取,从而检索到更多的相关信息。
而当搜索者点击浏览该网页的时候,也同样需要搜索者提供相应的权限验证才能够完全访问,这也就减少了人工搜索的工作量。
3.2网页文本的信息提取
通过搜索引擎建立网页索引,而处理的内容实质上是文本文件。
对于网络蜘蛛来讲,抓取的网页有多种格式的文件,比如:
网页文件(HTML、JavaScript)、图片文件(JPG、GIF)、文档文件(TXT、DOC、PDF)、多媒体文件(MP3音频、MP4视频)以及其它格式等。
当这些文件都被抓取之后,需要对这些文件进行文本提取处理,提取出关键信息并将其他其他格式文件过滤掉。
采用何种方法提取这些文本信息与过滤掉其他格式文件,方法的选取会对网络蜘蛛跟踪其它链接的准确性产生一定的影响。
对于文档文件来说,它可以看成由相关软件生成的对应文本,比如DOC文件,它是由Word软件生成的。
若要读取DOC文件时,Word运营商会提供Word的文本提取接口。
而网络蜘蛛也只需要通过调用该软件插件的接口,就可以很容易的获取DOC文件中中的文本信息以及文件其它相关的信息。
网页文本则不一样,如果网页为静态网页,则只需要处理HTML文件文本。
HTML拥有一套自己的语法体系,它能通过各种各样的命令标识符来显示不同样式(如:
加粗、滑动、颜色)。
当我们提取文本信息时,这些命令标识符都要被过滤掉。
其实,过滤这些命令标识符也并不是很难。
因为命令标识符都有一定的语法规则,只需要根据不同的命令标识符将相应的信息提取出来即可。
如果网页为动态网页,则可能会存在JavaScript文本。
类似的,JavaScript也有自己的语法规则,但不同的是JavaScript只是一种脚本语言,没有严格的语法规则。
如果要正确的处理好这些网页脚本,那么网络蜘蛛就需有一套自己的完整的脚本解释程序。
对于大部分数据是存放在数据库的网站来说,若想获得该网站的信息,就需要访问该网站的数据库才能获得,这些就会给网络蜘蛛带来较大的抓取困难。
像这类网站,如果网站管理员希望这些数据能被检索到,就需要提供一种可以访问整个数据库内容的方法。
否则,很难彻底对该网站的进行访问。
对于图片文件和多媒体文件来说,可以通过链接文本和相关的文件注释来判断这些文件的内容。
此外,一些多媒体文件当中会有文件属性参数,利用好这些属性参数也能较好的了解文件的格式。
因此,网页内容的合理提取是网络蜘蛛中关键的技术。
本系统一般会采用插件接口的形式,即使遇到不同文件格式的网页,通过插件管理服务程序,采用不同的插件处理,便可以完成网页内容的提取工作。
这种方式的优点在于可扩充性,系统运行之后每出现一种新的类型网页,则可以将其处理方式封装成一个插件程序,然后再添加到插件管理服务程序之中。
3.3HTML结构解析
3.3.1网页中的超链接
HTML全称HyperTextMarkupLanguage,即超文本标记语言。
作为一个组织或者个人在万维网上放置开始点的页面被称为主页或首页,主页中通常包括有指向其他相关页面或其他节点的指针(即超级链接),所谓的超级链接,它就是统一资源定位器URL(即UniformResourceLocator),通过单击它,可以让浏览器快速获取新的网页地址。
当网络蜘蛛在获得了HTML文本内容之后,提取其中的所需的关键信息,保存子链接URL并处理刷题的答案文本。
下面介绍两种常用的超链接:
1.文本链接test
2.图像链接
标签中的href所引入的链接一般是链向其他的WEB页面,是文本信息提取的目标子链接,需要保存下来。
是导入图片,对于文本信息提取并没有实际价值,所以也不需要保存,直接过滤掉。
3.3.2网页解析
对HTML的解析是正确提取HTML文件文本中的链接和文本内容的首要问题。
由于HTML的是语法比较灵活,比如标签
所对应的关闭标签
是可有可无的,相比而言,XML的语法定义就严格很多。
编写HTML相对来说也比较轻松,但是对于读取和解析HTML操作来说则要困难得多。
解析诸如C#或XML这样的具有准确定义、不允许有语法错误的语言,相对来讲则要容易的多,而解析HTML这样语法灵活的语言,解析起来也会存在一定困难,需要专门的HTML解析器。
本课题之所以采用C#开发,主要是采用.NET自带的webBrowser控件结合HtmlDocument进行解析。
虽然.NET提供了WebClient类和HttpWebRequest类能够访问并获得服务器端的网页数据。
这些类通过HTTP能够访问服务器端的网页并且能够将网页下载下来,但是若要解析下载下来的网页,则这些类的解析功能并不是那么完善,因此开发者不得不采用一些很原始的方法,比如使用String类的IndexOf()方法和Substring()方法或使用正则表达式去解析下载下来的网页。
显然,这些原始方法会显得很笨拙,因此,网页内容解析需要引入HTMLAgilityPack。
HTMLAgilityPack提供了一个由C#实现的开放式源代码的HTML解析器。
它的设计目标是尽可能简化对HTML文档的读和写。
这个包本身是借助了文档对象模型(即DocumentObjectModel,简称DOM)去解析HTML网页内容的。
仅仅通过几行代码,开发者就可以通过文档对象模型去访问HTML文档中的头部一直到它的孩子结点。
HTMLAgilityPack能通过XPath(即XML路径语言)访问到DOM中的指定结点,同时,它也具有下载服务器端网站上的网页内容的功能,这意味者开发者可以利用它,同时下载并且解析HTML网页内容,这相对于上述WebClient类和HttpWebRequest类来说就方便不少了。
在HTMLAgilityPack中经常使用的类会涉及到HtmlDocument类、HtmlNodeCollection类、HtmlNode类和HtmlWeb类等。
使用HTMLAgilityPack解析网页内容,其流程是:
首先获取网页。
通过HtmlDocument类Load()方法或LoadHtml()方法来加载网页,或者也可以HtmlWeb类的Get()方法或Load()方法来加载网页。
在获取了网页之后,就可以使用HtmlDocument类的DocumentNode属性,该属性是整个网页内容的根节点,本身也相当于是一个HtmlNode对象,然后就能够通过HtmlNode类的SelectNodes()方法返回包含多个HtmlNode的集合对象HtmlNodeCollection,也可以通过HtmlNode类的SelectSingleNode()方法返回单个HtmlNode对象。
下面简要分析下HTMLAgilityPack中的HTML过滤器的类:
(1)HtmlDocument类
在解析HTML内容之前需要加载好HTML源文件,HtmlDocument类中封装好了该功能的方法。
在HtmlDocument类中定义了重载的Load()方法来实现不同方式加载HTML,其实,主要分为如下两类:
1.以给定的Stream对象为主的有:
(1)publicvoidLoad(Streamstream)//从给定的Stream对象中加载html;
(2)publicvoidLoad(Streamstream,Encodingencoding)//给定编码格式另外一种是以给定的Stream对象为主;
2.以给定的物理路径为主的有:
(1)publicvoidLoad(stringpath)//从给定的path路径中加载html;
(2)publicvoidLoad(stringpath,Encodingencoding)//给定编码格式;
HtmlDocument类中还定义了直接从html字符串中加载Html,方法如下:
publicvoidLoadHtml(stringhtml)//从给定的html字符串中加载html;
(2)HtmlNode类
通过HtmlDocument类的Load()方法完成对HTML的加载,解析该网页内容时就需要HtmlNode类来实现。
在HtmlNode类中,可以了解到该类提供了一些查找当前节点下的子节点的方法,比如:
查找当前节点的父节点的方法。
如果你想获取一个给定元素的HtmlNode,可以借助HtmlDocument类的GetElementById(stringID)方法来获取,返回值为指定的某一个HTML元素的HtmlNode对象。
HtmlNode类的主要属性有:
(1)Attributes属性
该属性主要是获取当前HTML元素的属性的集合,返回值为HtmlAttributeCollection对象。
例如:
***