摘 要:使用ja字符串处理和多线程并发技术,构造实用的页面解析工具,实现网站内容高效、低噪地批量析取.
关 键 词 :噪音;线程;析取
随着网络应用的普及、使用、加工网站信息的需求日益增多,如何方便、及时、快捷的获取互联网网站的信息成为网络编程开发的一项新课题.近年来,ja技术在网络编程领域悄然兴起,在各种开源产品的支持下,ja技术的应用如火如荼,网站信息的析取方面,出现了DOM、SAX等成熟的开发技术,这些技术的基本特征是先格式化网站页面,再使用标签模板过滤析取相关内容,但是了解并掌握这些技术需要有较高的ja开发水平,对于ja的初学者来说学习消化的周期比较长,难以上手.
笔者曾利用字符串处理等较易掌握的技术开发出了网站信息的批量析取系统,在实际工作中取得了较好的应用效果,在此共享出来,供各位读者参考.
1.网站页面析取
这是系统功能实现的基础,把网站页面转换为可以操作的字符串形式,这里使用了一款开源产品HTMLPARSER,笔者通过实际测试,发现HTMLPARSER比其他同类产品(如Jtidy等)的容错性、通用性更好,解析页面的完整度更高,具体做法如下:
有关论文范文主题研究: | 关于数据库的论文范文集 | 大学生适用: | 专升本论文、学年论文 |
---|---|---|---|
相关参考文献下载数量: | 39 | 写作解决问题: | 本科论文怎么写 |
毕业论文开题报告: | 论文任务书、论文结论 | 职称论文适用: | 刊物发表、中级职称 |
所属大学生专业类别: | 本科论文怎么写 | 论文题目推荐度: | 经典题目 |
1.1 构造解析器
这里采用LinkTag.class格式解析页面中的部分,可以解析到jascript的跳转代码,而HTMLPARSER中推荐的StringExtractor用法只能解析到
核心代码如下:
NodeFilter filter 等于 new NodeClassFilter(LinkTag.class),
Parser parser 等于 new Parser(),
parser.setURL(url),//url:需要解析的页面地址
parser.setEncoding(codeset),//codeset:页面编码设置
NodeList list 等于 parser.extractAllNodesThatMatch(filter),
list就是解析出的结果集,再使用toHtml()方法就能得到一般的代码了:
for (int i 等于 0, i < list.size(), i++)
{
String s[i]等于 list.elementAt(i).toHtml(),
}
至此,系统完成了页面解析工作,网站页面转换成了普通的代码,存入数组s中,为下一步进行字符串操作做好准备.
1.2 页面内容抽取
页面转换完成后,如何从一大堆字符中获取需要的文本呢?目前许多做法是使用DOM技术进行节点遍历,但是由于封装了许多底层的操作,使得程序灵活性、执行效率大打折扣,同时页面的匹配问题使得抽取内容不可避免的带有噪声.
进行网站页面的抽取工作应该是基于这样一个前提:网站页面是由统一的发布系统生成的,页面具有统一的样式.如果没有这样一个前提,那么任何一个工具都不可能对样式繁多的页面进行统一匹配.如果不能对页面实行统一匹配,那批量抽取也就不可能了,页面内容的抽取就失去了意义.如今大型网站内容的发布基本上都是使用统一的发布工具进行的,这就使得网站页面具有统一的格式,具备了内容抽取的应用前提.
经过解析器的解析,就可以使用ja方便的字符处理功能对规律性页面内容进行抽取,笔者开发的系统以用户指定的标题页面为起始点,自动抽取页面中所有标题的内容,以下是抽取代码片段:
/*--参数说明--
t_start:开始析取具体标题行的起始标志
l_start:标题页面超联区域起始点标识串
l_end:标题页面超联区域终结点标识串
l_len:l_start的字符串长度
txt_start:内容页面起始标识串
txt_len:txt_start字符串的长度
txt_end:内容页有效区域终结点标识
*/
等
for (int i 等于 0, i < list.size(), i++)
{
if(s[i].indexOf(t_start)!等于-1)
{
s1等于s[i].substring(s[i].indexOf(l_start)+l_len),
m[n][0]等于s1.substring(0,s1.indexOf(l_end)), //标题超联
s3等于s1.substring(s1.indexOf(">")+1),
s3等于s3.replaceAll("[<][^>]*",""),
m[n][1]等于s3.replaceAll("[>]",""),//标题主体
try
{
//获得具体内容
StringExtractor xx等于new StringExtractor(m[n][0]),
String yy等于xx.extractStrings(false),
if(txt_start.equals(""))
{
m[n][2]等于yy.substring(yy.indexOf(s3.trim()),yy.indexOf(txt_end)),
}
else
{
m[n][2]等于yy.substring(yy.indexOf(txt_start)+txt_len,yy.indexOf(txt_end)),
}
n++,//数组增加一行
}
等
}
}
等
执行完成后,页面的链接、标题和内容就储存在二维数组m中,其行数就是页面包含的标题条数.然后可以根据需要利用ja的数据库操作或文件操作,将数组m中的数据存入数据库或写成文本文件.
通过字符串操作方式抽取出的文本最大的特点是数据噪音小,更加干净,便于进一步的分析使用.
2.析取数据的批量操作
通过页面解析与内容抽取,已经可以非常轻松地得到页面干净的纯文本数据,接下来的工作就是让计算机高效率地为我们析取多个网站的页面,这里需要使用ja的多线程技术.
从便于代码封装的角度考虑,笔者使用 Runnable 接口来实现多线程,把第一部分中页面内容析取代码统一写成一个方法,再创建 一个Thread 类的实例,并将该方法置入run()中,实现多线程的并发运行.相关ja多线程的开发细节读者可以去查阅具体开发手册,在这里重点阐述一下线程同步过程中的关键点,即共享互斥的控制.
在Ja中,当多个线程试图同时修改某个实例的内容时,就会造成冲突,要实现共享互斥,使多线程同步,最简单的方法是使用synchronized标记,对同一个实例来说,任一时刻只能有一个synchronized方法在执行.当一个方法正在执行某个synchronized方法时,其他线程如果想要执行这个实例的任意一个synchronized方法,都必须等待当前执行synchronized方法的线程退出此方法后,才能依次执行,因此对多线程共享互斥的控制关键是确定需要使用synchronized方法保护.
笔者将网站析取代码统一写成一个方法,主程序采用循环调用的方式启动多个并发线程,各个线程通过接受不同的页面参数来实现不同网站页面的析取,这就要确保线程参数在执行前不被置换,采用生产者――消费者模式,利用synchronized标记实现线程并发控制.核心代码如下:
//--主程序--
public static void main(String[] args)
{
int k等于0,
MultiExtractInfo r等于new MultiExtractInfo(),//初始化类
Thread[] th 等于 new Thread[20],//线程数量
for (k等于0,k<20,k++)
{
synchronized(r)
{
isdone等于false,
if (num>5) //线程最大并发量为6
{
isWait等于true,
}
while (isWait)
{
try
{
r.wait(),
}
等
}
r.SetV(),//析取页面参数赋值
th[k]等于new Thread(r),
th[k].start(),//启动线程
num++,
while (!isdone)
{
try
{
r.wait(),//等待析取页面参数被赋值
}
等
}
}
}
}
//--run方法--
public void run()
{
this.result_js(),//页面析取方法
synchronized(this)
{
if (num>0)
{
num--,
}
if(isWait)
{
isWait 等于 false,
this.notify(),
}
}
}
//--页面析取方法封装--
void result_js()
{
等
try
{
synchronized(this)
{
if (!isdone)
{
isdone等于true,
this.notify(),
}
}
等
}
等
}
这样,使用以上生产者――消费者模式,利用ja的synchronized标记,实现了多进程的并发运行.
3.系统运行
具备了页面析取的核心功能,接下来就是让系统在实际工作环境中有效运转起来,为此,还需要进行数据存储、数据连续析取等功能的开发.笔者将析取的内容放入数据库使用,析取的网站数据通过jdbc存入Ms SQL Server中,每次析取时将获得的数据与上次析取的最新数据比较,若相同则终止析取,若不同则存入数据库,以此实现数据的连续析取.读者也可以根据系统的核心功能在其他方面进行扩展,比如以文件和时间戳的方式实现析取数据的连续存储,为搜索引擎提供数据源等等.
笔者开发的网站信息批量析取系统目前正在安徽省政府网站管理平台上运行,在全省网站监督、信息采集等方面发挥了巨大作用.系统结构简洁、功能强大、伸缩性和适应性较好,运行至今,表现十分稳定,得到的数据噪音小,是一款高效、实用的应用系统.
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文.