网络数据库挖掘程序的设计

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

现在很多网页都是由数据库自动生成的,数据分散在html代码之中:有的位于URL链接中,有的位于<td></td>之中,有的位于javascript代码之中.如何挖掘这些数据为我所用?小的不才,最近写了一个网络数据库挖掘程序,挖掘了几千万条数据.源代码不能公开,这里简单述说一下设计思路和基本结构吧.

本来是用.net写的,写了几天,因为找不到好的c#html解析器,最后还是改成了java.在这里,我尽量从语言中性的角度来解释设计思路和关键点所在,就算是小项目分析吧,供大家参考.

设计目的:解析类如 http://xxx.xxx.xxx.xxx/xxx.xxxx?xxxxx={keyword}&xxxx=xxxx&xxxxxx={page}&xxxxxxx之类的网页.

这类网页一下特点 :

1,根据idkeyword由数据库动态生成

2,idkeyword针对1页或多页页面,可以通过翻页来浏览.翻页逻辑体现在url或内部html代码中.

3,每一页面有1条或多条数据,每条数据可根据一定的字符串模式匹配.

差不多大部分网络数据库都有这些特点,下面是一个例子:



 

软件结构如下图:



 

各部分角色如下:

(1) 控制器:调度线程,轮询线程,调度html解析器,抽取数据生成实体,调度数据接入逻辑,控制关键词生成逻辑,控制翻页逻辑

(2) 线程调度:生成线程,中止线程.

(3) html解析器:指定URL地址,负责获取页面,把页面解析成相应的NodeList.

(4) 实体:实体类,体现了实体逻辑.

(5) 数据存储:将已经获得的实体数据存储入数据库

下面逐一介绍,控制器逻辑最复杂,放在最后.

(1) html解析器

html解析器我找的是开源实现.找到几个.nethtml parser,老感觉不好用.接着又找java,先找到了JSpider,看了几天,觉得不能满足我的需求,最后找到htmlParser,决定用这个.

用到的htmlParser功能很简单:给出一个URL地址,生成一个parser,parser访问页面,根据过滤器类型,解析成一个个的NodeList,,包含<td>节点的NodeList,包含linkNodeList........使用很简单.

1 Parser htmlParser  =   new  Parser(urlString);  // 创建Parser:
2 NodeList allList  = htmlParser.parse( null );  // 获得所有节点
3 NodeList tdList  =  allList.extractAllNodesThatMatch( new  NodeClassFilter(TableColumn. class ), true );  // 获得td节点

htmlParser可以设置cookies.

因为htmlParser是调用block IO,所以需要在虚拟机上设置ConnectTimeoutReadTimeout,不设置的话,一旦网络慢下来,总会有几个线程在傻等.我觉得都设置为30秒比较合适.

(2) 实体

因为我要用OR-Mapping,所以就单独提取一个实体层出来.根据要挖掘的数据类型可构造出实体类这个就不详说了.

(3) 数据存储

采用OR-Mapping. 对于网络数据库,所设计的数据表的个数不多,于是偶将数据库访问逻辑再封装在类DatabaseHelper.DatabaseHelper作为数据层的Facade,所有上层数据访问必须通过DatabaseHelper进行.

DatabaseHelper有一个静态变量 private static boolean DEBUG = false; (c#格式: private static bool DEBUG = false)另外有一个方法:

1   public   static   void  Debug()
2      {
3        DEBUG = true;
4    }

调用DatabaseHelper.Debug()方法可以将DatabaseHelper设置为调试状态,所有读取数据库操作照常,只是不进行实质性的写入数据库操作.开发过程中因为要经常调试,为了不污染数据库,特意设计这个东东.

(4) 线程调度

采用Worker Thread模式.见偶的blog <调度模式·Worker-Channel-Request>. 控制器不断的向channel中放入Request, 工作线程获取并执行Request.

(5) 控制器

控制器由6个重要接口IDispatcher, IDispatcheHelper, ISpider, ISpiderHelper, IHandler, IDigger组成.每一个接口有对应的抽象类骨架,分别为: Dispatcher, DispatcheHelper, Spider, SpiderHelper, Handler, Digger. helper的都是可能调用DatabaseHelper的类.

下面详细介绍这些接口和基础类的功能:

  • IDispatcher Dispatcher:

IDispatcher主要有dispatch(),dispatch(Object key), registAfterCrawled(ISpider spider)三个方法运行dispatch(),则默认扫表网络数据库的所有的keywords, dispatch(Object key)只扫描数据库的指定的keyword.

针对每个keyword, Dispatcher将产生相应的ISpider,ISpider扫描完毕后通过registAfterCrawled(ISpider spider)通知Dispatcher.

具体的指派逻辑在Dispatcher中实现.主要逻辑如下:

(a) 通过IDispatcheHelper获得需要指派给Spiderkeywords(存入ElementsSet)和以往已指派抓取完毕的keywords(存入DispatchedSet).

(b) 通知Channel,开启全部工作线程.Dispatcher的构造函数Dispatcher(int threadCount),可指定开启的工作线程数.

(c) 再产生一个轮询线程,逐一轮询工作线程,查看线程执行状态.

(d) 遍历ElementsSet,对于其中的keyword,如果不在DispatchedSet之中,则指派keyword进行扫描

(e) 对于指派的keyword,产生一个Spider,包装成Request,放入Channel,供工作线程执行.

(e) 如果没有需要调度Request,则通知Channel,Request,工作线程执行完Channel上的Requests后自动中止.

  • IDispatchHelperDispatchHelper

IDispatchHelper的主要方法是getDispatchedSet()getElementsSet(),获得需要指派给Spiderkeywords(存入ElementsSet)和以往已指派的keywords(存入DispatchedSet). IDispatchHelper还有两个方法: isDispatched(Object  key)commit(Object key), 前一个用来查询某个keyword是否已指派抓取完成,后一个主要是供Dispatcher调用,在指派完一个Spider,Spider完成后通过调用registAfterCrawled,ElementsSet中注册,表明已指派完该keyword.

getDispatchedSet()getElementsSet(),可以从数据库中生成也可以从文件中读取,也可以是根据某些逻辑条件生成.

  • ISpider, Spider , ISpiderHelperSpiderHelper

ISpiderSpider的角色是根据指定的keyword,获取该keyword的所有查询页面的数据,生成实体,并存储入数据库. Spider包装在Request,一个线程一次只能调用一个Request,也就是一个线程一次只能执行一个Spider.

ISpider的主要方法是crawl(),负责所有的爬行逻辑和后续操作,具体逻辑封装在. Spider之中.

1Spider拥有1SpiderHelper1Handler. SpiderHelper主要作用是(1)从数据库中获取该keyword已经抓取的纪录CrawledSet(因为可能由于网络原因,有的Spider抓了一半,就停止了,但数据库中已经抓了不少纪录);(2) 通过dump(digger)digger抓取的数据存储入数据库.Hander的作用是(1)判断是否还有下一页,(2)构建当前页的URL,根据URL产生Parser,Parser产生Digger.

crawl()的代码骨干如下:

1         IDigger digger;
2          while  ((digger  =   this .handler.next())  !=   null {
3            this.helper.dump(digger);
4        }

5          this .helper.saveRecord();

this.helper.saveRecord() 作用更新数据库中数据 , 表明该 keyword 对应数据已经抓取完毕 . 这样 , 当再次运行程序 , IDispatchHelper. getElementsSet() 就不会包含该 Spider 所对应的 keyword .

  • IHandler, Handler

IHandler 的主要方法是IDigger.next(),获得下一页所对应的IDigger.不存在则返回null.

Hander有几个主要的抽象方法根据页数构造URL--buildUrlString(int pageage), 根据所构造的URL构造Parser--buildParser(), 根据Parser构造Digger--buildDigger().

IHandler .next()根据Parser所返回来的NodeList判断是否存在下一个页面(具体的判断逻辑由具体类实现),如果有则根据下一页的页数,重新一次调用buildUrlString(int pageage), buildParser(),buildDigger(),返回IDigger.

  • IDigger  Digger

IDigger  Digger主要作用是分析Parser所抓获解析所得的页面NodeList,解析成实体对象.

IDigger的主要方法是获取实体--ArrayList dig()和获取当前页面的URL--String getUrlString().Digger提供了protected NodeList getTdList(),protected NodeList getLinkList(),...........等方法,供具体类调用具体的解析逻辑就在Digger的具体类中的实现了.


进一步的做法是从中提出一般性框架出来
,然后还需要一套规则体系.就看有没时间了.:P

本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2005/12/06/291569.html如需转载请自行联系原作者


xiaotie 集异璧实验室(GEBLAB)

相关文章
用MASM32按Time Protocol(RFC868)协议编写网络对时程序中的一些有用的函数代码
用MASM32按Time Protocol(RFC868)协议编写网络对时程序中的一些有用的函数代码
|
22天前
|
网络协议 物联网 数据处理
C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势
本文探讨了C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势。文章详细讲解了使用C语言实现网络通信程序的基本步骤,包括TCP和UDP通信程序的实现,并讨论了关键技术、优化方法及未来发展趋势,旨在帮助读者掌握C语言在网络通信中的应用技巧。
34 2
|
29天前
|
数据库连接 Go 数据库
Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性
本文探讨了Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性;防御编程则强调在编码时考虑各种错误情况,确保程序健壮性。文章详细介绍了这两种技术在Go语言中的实现方法及其重要性,旨在提升软件质量和可靠性。
29 1
|
1月前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
598 2
|
6月前
|
机器学习/深度学习 存储 自然语言处理
程序与技术分享:DeepMemoryNetwork深度记忆网络
程序与技术分享:DeepMemoryNetwork深度记忆网络
|
3月前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
201 5
|
2月前
|
安全 网络协议 IDE
使用Python编写网络扫描程序
使用Python编写网络扫描程序
54 0
|
4月前
|
存储 网络协议 安全
|
5月前
|
机器学习/深度学习 数据采集 监控
基于CNN卷积神经网络的步态识别matlab仿真,数据库采用CASIA库
**核心程序**: 完整版代码附中文注释,确保清晰理解。 **理论概述**: 利用CNN从视频中学习步态时空特征。 **系统框架**: 1. 数据预处理 2. CNN特征提取 3. 构建CNN模型 4. 训练与优化 5. 识别测试 **CNN原理**: 卷积、池化、激活功能强大特征学习。 **CASIA数据库**: 高质量数据集促进模型鲁棒性。 **结论**: CNN驱动的步态识别展现高精度,潜力巨大,适用于监控和安全领域。
|
4月前
|
数据库连接 数据库
实现加载驱动、得到数据库对象、关闭资源的代码复用,将代码提取到相应的工具包里边。优化程序
该博客文章展示了如何通过创建工具类`Connectiontools`实现数据库连接、语句执行以及资源关闭的代码复用,以优化程序并提高数据库操作的效率和安全性。
下一篇
DataWorks