Reader's Digest

Digest your Internet

ASP 编程中 20 个非常有用的例子——适合初学者

Written By: dch1 - May• 01•08

1.如何用Asp判断你的网站的虚拟物理路径
答:使用Mappath方法

The Physical path to this virtual website is:

 
2.我如何知道使用者所用的浏览器?
答:使用the Request object方法
strBrowser=Request.ServerVariables(“HTTP_USER_AGENT”)
If Instr(strBrowser,”MSIE”)  0 Then
  Response.redirect(“ForMSIEOnly.htm”)
Else
  Response.redirect(“ForAll.htm”)
End If
3.如何计算每天的平均反复访问人数
答:解决方法
< % startdate=DateDiff(“d”,Now,”01/01/1990″)
if strdate
显示结果

that is it.this page have been viewed since November 10,1998
4.如何显示随机图象

显示
< img src=”” >
5.如何回到先前的页面
答:< a href=”” >preivous page
或用图片如:< img src=”arrowback.gif” alt=”” >
6.如何确定对方的IP地址
答:
7.如何链结到一副图片上
答:

8.强迫输入密码对话框
答:把这句话放载页面的开头

9.如何传递变量从一页到另一页
答:用 HIDDEN 类型来传递变量
< input namee=”” type=”HIDDEN”
value=”” >
10.为何我在 asp 程序内使用 msgbox,程序出错说没有权限
答:由于 asp 是服务器运行的,如果可以在服务器显示一个对话框,那么你只好等有人按了确定之后,你的程序才能继续执行,而一般服务器不会有人守着,所以微软不得不禁止这个函数,并胡乱告诉你 ( 呵呵) 没有权限。但是ASP和客户端脚本结合倒可以显示一个对话框,as follows:
alert(“”)

11.有没有办法保护自己的源代码,不给人看到
答:可以去下载一个微软的Windows Script Encoder,它可以对asp的脚本和客户端javascript/vbscript脚本进行加密。。。不过客户端加密后,只有ie5才能执行,服务器端脚本加密后,只有服务器上安装有script engine 5(装一个ie5就有了)才能执行。
12.怎样才能将 query string 从一个 asp 文件传送到另一个?
答:前者文件加入下句: Response.Redirect(“second.asp?” & Request.ServerVariables(“QUERY_STRING”))
13.global.asa文件总是不起作用?
答:只有web目录设置为web application, global.asa才有效,并且一个web application的根目录下 global.asa才有效。IIS4可以使用Internet Service Manager设置application setting 怎样才能使得htm文件如同asp文件一样可以执行脚本代码?
14.怎样才能使得htm文件如同asp文件一样可以执行脚本代码?
答:Internet Sevices Manager – > 选择default web site – >右鼠键- >菜单属性-〉主目录- > 应用程序设置(Application Setting)- > 点击按钮 “配置”- > app mapping – >点击按钮”Add” – > executable browse选择 \WINNT\SYSTEM32\INETSRV\ASP.DLL EXTENSION 输入 htm method exclusions 输入PUT.DELETE 全部确定即可。但是值得注意的是这样对htm也要由asp.dll处理,效率将降低。
15.如何注册组件
答:有两种方法。
第一种方法:手工注册 DLL 这种方法从IIs 3.0一直使用到IIs 4.0和其它的Web Server。它需要你在命令行方式下来执行,进入到包含有DLL的目录,并输入:regsvr32 component_name.dll 例如 c:\temp\regsvr32 AspEmail.dll 它会把dll的特定信息注册入服务器中的注册表中。然后这个组件就可以在服务器上使用了,但是这个方法有一个缺陷。当使用这种方法注册完毕组件后,该组件必须要相应的设置NT的匿名帐号有权限执行这个dll。特别是一些组件需要读取注册表,所以,这个注册组件的方法仅仅是使用在服务器上没有MTS的情况下,要取消注册这个dll,使用:regsvr32 /u aspobject.dll example c:\temp\regsvr32 /u aneiodbc.dll
第二种方法:使用MTS(Microsoft Transaction Server) MTS是IIS 4新增特色,但是它提供了巨大的改进。MTS允许你指定只有有特权的用户才能够访问组件,大大提高了网站服务器上的安全性设置。在MTS上注册组件的步骤如下:
1) 打开IIS管理控制台。
2) 展开transaction server,右键单击”pkgs installed”然后选择”new package”。
3) 单击”create an empty package”。
4) 给该包命名。
5) 指定administrator帐号或则使用”interactive”(如果服务器经常是使用administrator 登陆的话)。
6) 现在使用右键单击你刚建立的那个包下面展开后的”components”。选择 “new then component”。
7) 选择 “install new component” 。
8) 找到你的.dll文件然后选择next到完成。
要删除这个对象,只要选择它的图标,然后选择delete。
附注:特别要注意第二种方法,它是用来调试自己编写组件的最好方法,而不必每次都需要重新启动机器了。
16. ASP与Access数据库连接:
17. ASP与SQL数据库连接:
建立记录集对象:
set rs=server.createobject(“adodb.recordset”)
rs.open SQL语句,conn,3,2
18. SQL常用命令使用方法:
(1) 数据记录筛选:
sql=”select * from 数据表 where 字段名=字段值 order by 字段名 [desc]”
sql=”select * from 数据表 where 字段名 like ‘%字段值%‘ order by 字段名 [desc]”
sql=”select top 10 * from 数据表 where 字段名 order by 字段名 [desc]”
sql=”select * from 数据表 where 字段名 in (‘值1‘,‘值2‘,‘值3‘)”
sql=”select * from 数据表 where 字段名 between 值1 and 值2″
(2) 更新数据记录:
sql=”update 数据表 set 字段名=字段值 where 条件表达式”
sql=”update 数据表 set 字段1=值1,字段2=值2 …… 字段n=值n where 条件表达式”
(3) 删除数据记录:
sql=”delete from 数据表 where 条件表达式”
sql=”delete from 数据表” (将数据表所有记录删除)
(4) 添加数据记录:
sql=”insert into 数据表 (字段1,字段2,字段3 …) valuess (值1,值2,值3 …)”
sql=”insert into 目标数据表 select * from 源数据表” (把源数据表的记录添加到目标数据表)
(5) 数据记录统计函数:
AVG(字段名) 得出一个表格栏平均值
COUNT(*|字段名) 对数据行数的统计或对某一栏有值的数据行数统计
MAX(字段名) 取得一个表格栏最大的值
MIN(字段名) 取得一个表格栏最小的值
SUM(字段名) 把数据栏的值相加
引用以上函数的方法:
sql=”select sum(字段名) as 别名 from 数据表 where 条件表达式”
set rs=conn.excute(sql)
用 rs(“别名”) 获取统的计值,其它函数运用同上。
(5) 数据表的建立和删除:
CREATE TABLE 数据表名称(字段1 类型1(长度),字段2 类型2(长度) …… )
例:CREATE TABLE tab01(name varchar(50),datetime default now())
DROP TABLE 数据表名称 (永久性删除一个数据表)
19. 记录集对象的方法:
rs.movenext 将记录指针从当前的位置向下移一行
rs.moveprevious 将记录指针从当前的位置向上移一行
rs.movefirst 将记录指针移到数据表第一行
rs.movelast 将记录指针移到数据表最后一行
rs.absoluteposition=N 将记录指针移到数据表第N行
rs.absolutepage=N 将记录指针移到第N页的第一行
rs.pagesize=N 设置每页为N条记录
rs.pagecount 根据 pagesize 的设置返回总页数
rs.recordcount 返回记录总数
rs.bof 返回记录指针是否超出数据表首端,true表示是,false为否
rs.eof 返回记录指针是否超出数据表末端,true表示是,false为否
rs.delete 删除当前记录,但记录指针不会向下移动
rs.addnew 添加记录到数据表末端
rs.update 更新数据表记录
---------------------------------------
20 Recordset对象方法
Open方法
recordset.Open Source,ActiveConnection,CursorType,LockType,Options
Source
Recordset对象可以通过Source属性来连接Command对象。Source参数可以是一个Command对象名称、一段SQL命令、一个指定的数据表名称或是一个Stored Procedure。假如省略这个参数,系统则采用Recordset对象的Source属性。
ActiveConnection
Recordset对象可以通过ActiveConnection属性来连接Connection对象。这里的ActiveConnection可以是一个Connection对象或是一串包含数据库连接信息(ConnectionString)的字符串参数。
CursorType
Recordset对象Open方法的CursorType参数表示将以什么样的游标类型启动数据,包括adOpenForwardOnly、adOpenKeyset、adOpenDynamic及adOpenStatic,分述如下:
————————————————————–
常数 常数值 说明
————————————————————-
adOpenForwardOnly 0 缺省值,启动一个只能向前移动的游标(Forward Only)。
adOpenKeyset 1 启动一个Keyset类型的游标。
adOpenDynamic 2 启动一个Dynamic类型的游标。
adOpenStatic 3 启动一个Static类型的游标。
————————————————————-
以上几个游标类型将直接影响到Recordset对象所有的属性和方法,以下列表说明他们之间的区别。
————————————————————-
Recordset属性 adOpenForwardOnly adOpenKeyset adOpenDynamic adOpenStatic
————————————————————-
AbsolutePage 不支持 不支持 可读写 可读写
AbsolutePosition 不支持 不支持 可读写 可读写
ActiveConnection 可读写 可读写 可读写 可读写
BOF 只读 只读 只读 只读
Bookmark 不支持 不支持 可读写 可读写
CacheSize 可读写 可读写 可读写 可读写
CursorLocation 可读写 可读写 可读写 可读写
CursorType 可读写 可读写 可读写 可读写
EditMode 只读 只读 只读 只读
EOF 只读 只读 只读 只读
Filter 可读写 可读写 可读写 可读写
LockType 可读写 可读写 可读写 可读写
MarshalOptions 可读写 可读写 可读写 可读写
MaxRecords 可读写 可读写 可读写 可读写
PageCount 不支持 不支持 只读 只读
PageSize 可读写 可读写 可读写 可读写
RecordCount 不支持 不支持 只读 只读
Source 可读写 可读写 可读写 可读写
State 只读 只读 只读 只读
Status 只读 只读 只读 只读
AddNew 支持 支持 支持 支持
CancelBatch 支持 支持 支持 支持
CancelUpdate 支持 支持 支持 支持
Clone 不支持 不支持
Close 支持 支持 支持 支持
Delete 支持 支持 支持 支持
GetRows 支持 支持 支持 支持
Move 不支持 支持 支持 支持
MoveFirst 支持 支持 支持 支持
MoveLast 不支持 支持 支持 支持
MoveNext 支持 支持 支持 支持
MovePrevious 不支持 支持 支持 支持
NextRecordset 支持 支持 支持 支持
Open 支持 支持 支持 支持
Requery 支持 支持 支持 支持
Resync 不支持 不支持 支持 支持
Supports 支持 支持 支持 支持
Update 支持 支持 支持 支持
UpdateBatch 支持 支持 支持 支持
————————————————————–
其中NextRecordset方法并不适用于Microsoft Access数据库。
LockType
Recordset对象Open方法的LockType参数表示要采用的Lock类型,如果忽略这个参数,那么系统会以Recordset对象的LockType属性为预设值。LockType参数包含adLockReadOnly、adLockPrssimistic、adLockOptimistic及adLockBatchOptimistic等,分述如下:
————————————————————-
常数 常数值 说明
————————————————————–
adLockReadOnly 1 缺省值,Recordset对象以只读方式启动,无法运行AddNew、Update及Delete等方法
adLockPrssimistic 2 当数据源正在更新时,系统会暂时锁住其他用户的动作,以保持数据一致性。
adLockOptimistic 3 当数据源正在更新时,系统并不会锁住其他用户的动作,其他用户可以对数据进行增、删、改的操作。
adLockBatchOptimistic 4 当数据源正在更新时,其他用户必须将CursorLocation属性改为adUdeClientBatch才能对数据进行增、
删、改的操作.

在FLASH中调用ASP

Written By: dch1 - May• 01•08
在FLASH中调用ASP

在Flash中使用ASP需要的条件:
1。你的ISP的server必须支持Active Server Pages并且最好支持数据库
2。你应该要安装Flash 4
3。需要你对ASP有初步的了解
OK,下面具体介绍怎么使用:
数据库结构:
第一步要做的是建立数据库.例子中使用Access数据库,表名为tblStaff
有三个字段:strID (自动编号), strKnownAs(Text),strSurname (Text).
这是一个用来示范用户名的数据库,随便加些数据把.
第二步就是建立一个Flash 4的动画罗:
步骤如下:
1)建立三个text field.它们是用来显示数据用的
2)把第一个text field的name设置为Input,它是用来接收输入数据的
3)另外两个text field分别命名为KnownAs和Surname
4)其它设置先为默认
5)最后,从Flash的library中选择增加一个按钮 (应该是一个可重用的组件ScrollBarButton ).
这是很重要的一步,按钮将把输入的变量传递给ASP页面到按钮的属性(Properties)上单击Action页. 单击”+”号和On MouseEvent.勾上Release框.
6)再次单击”+”号和Load/Unload Movie.选择”Load Variables Into Location”
在URL输入框内输入你的ASP文件名(例如flash.asp). 选择Target.
7)最后,选择Variables中的Send using POST. 单击”+”号来设置变量
在Variable输入框内输入”Input”(就是第一个text field的name)
当上面的工作都完成后,你应该在action box内看到如下内容:
On (Release)
Load Variables (“flash.asp”, “”, vars=POST)
Set Variable: “Input” = “”
End On
这样当在动画过程中这个按钮被点击并释放后,Input输入框中的内容将被传递给flash.asp文件.
注意form是使用的post方式传递变量的.
8)现在建立一个HTML页面,在其中包含这个Flash动画文件
第三步:ASP文件的代码
<%
Set Connection = Server.CreateObject(“ADODB.Connection”)
Set Recordset = Server.CreateObject(“ADODB.Recordset”)
Connection.Open “people” ´你的数据库连接的DSN
SQL = “SELECT * FROM tblStaff WHERE strID=” & Request.Form(“Input”) & “;”
Recordset.Open SQL,Connection,1,2
If Recordset.EOF Then
KnownAs = “Not”
Surname = “Found”
Else
KnownAs = Recordset (“strKnownAs”)
Surname = Recordset (“strSurname”)
End If
Recordset.Close
Connection.Close
response.write(“KnownAs=”+Server.URLEncode(KnownAs))
response.write(“&Surname=”+Server.URLEncode(Surname))
%>
需要注意的是在把KnownAs和Surname传递回去的写法,将是这样的
KnownAs=Data1&Surname=Data2
使用Server.URLEncode(VariableName)来保证传递过去变量的是按照 URL格式编码的
下面简单介绍一下ASP和Flash通讯的原理:
变量其实都是通过URL传递给Flash的,其实这是一种GET方法
你不使用ASP其实也可以把变量传递给一个swf文件的,只要这样:
<PARAM NAME=movie VALUE=”myMovie.swf?myVariable=Text+of+my+variable”>
接着文本”Text of my variable”将会出现在Flash的动画中指定的位置
好了,该说的都说了,现在对于ASP的开发者来说,只要把Flash所需要的数据准备好,然后利用Flash中的动画
功能就可以做出强劲的网页出来了.最简单的是利用flash结合数据库画一个很漂亮的饼图,呵呵.反正只要大家能够想象就可以做出很多很好的东西出来的.

Web搜索引擎设计和实现分析

Written By: dch1 - May• 01•08
—- 一、引言

—- 随着Internet的飞速发展,人们越来越依靠网络来查找他们所需要的信息,但是,由于网上的信息源多不胜数,也就是我们经常所说的”Rich Data, Poor Information”。所以如何有效的去发现我们所需要的信息,就成了一个很关键的问题。为了解决这个问题,搜索引擎就随之诞生。

—- 现在在网上的搜索引擎也已经有很多,比较著名的有AltaVista, Yahoo, InfoSeek, Metacrawler, SavvySearch等等。国内也建立了很多的搜索引擎,比如:搜狐、新浪、北极星等等,当然由于它们建立的时间不长,在信息搜索的取全率和取准率上都有待于改进和提高。

—- Alta Vista是一个速度很快的搜索引擎,由于它强大的硬件配置,使它能够做及其复杂的查询。它主要是基于关键字进行查询,它漫游的领域有Web和Usenet。支持布尔查询的”AND”,”OR”和”NOT”,同时还加上最相近定位”NEAR”,允许通配符和”向后”搜索(比如:你可以查找链接到某一页的所有Web站点)。你可以决定是否对搜索的短语加上权值,在文档的什么部位去查找它们。能够进行短语查询而不是简单的单词查询的优点是很明显的,比如,我们想要查找一个短语”to be or not to be”,如果只是把它们分解成单词的话,这些单词都是属于Stop Word,这样这个查询就不会有任何结果,但是把它当作一个整体来查询,就很容易返回一些结果,比如关于哈姆雷特或者是莎士比亚等等的信息。系统对查询结果所得到的网页的打分是根据在网页中所包含的你的搜索短语的多少,它们在文档的什么位置以及搜索短语在文档内部之间的距离来决定的。同时可以把得到的搜索结果翻译成其他的语言。

—- Exite是称为具有”智能”的搜索引擎,因为它建立了一个基于概念的索引。当然,它所谓的”智能”是基于对概率统计的灵活应用。它能够同时进行基于概念和关键字的索引。它能够索引Web,Usenet和分类的广告。支持”AND”,”OR”,”NOT”等布尔操作,同时也可以使用符号”+”和”-“。缺点是在返回的查询结果中没有指定网页的尺寸和格式。

—- InfoSeek是一个简单但是功能强大的索引,它的一个优点是有一个面向主题搜索的可扩展的分类。你可以把你的搜索短语和相似的分类目录的主题短语相互参照,而那些主题短语会自动加到你的查询中去。使你的搜索有更好的主题相关性。同时它也支持对图象的查询。它能够漫游Web,Usenet,Usenet FAQs等等。不支持布尔操作,但是可以使用符号”+”和”-“(相当于”AND”和”NOT”)

—- Yahoo实际上不能称为是一个搜索引擎站点,但是它提供了一个分层的主题索引,使你能够从一个通常的主题进入到一个特定的主题,Yahoo对Web进行了有效的组织和分类。比如你想要建立一个网页,但是你不知道如何操作,为了在Yahoo上找到关于建立网页的信息,你可以先在Yahoo上选择一个主题:计算机和Internet,然后在这个主题下,你可以发现一些子主题,比如:Web网页制作,CGI编程,JAVA,HTML,网页设计等,选择一个和你要找的相关的子主题,最终你就可以得到和该子主题相关的所有的网页的链接。也就是说,如果你对要查找的内容属于哪个主题十分清楚的话,通过目录查询的方法要比一般的使用搜索引擎有更好的准确率。你可以搜索Yahoo的索引,但是事实上,你并没有在搜索整个Web。但是Yahoo提供了选项使你可以同时搜索其他的搜索引擎,比如:Alta Vista。但是要注意的是Yahoo实际上只是对Web的一小部分进行了分类和组织,而且它的实效性也不是很好。

—- 搜索引擎的基本原理是通过网络机器人定期在web网页上爬行,然后发现新的网页,把它们取回来放到本地的数据库中,用户的查询请求可以通过查询本地的数据库来得到。如yahoo每天会找到大约500万个新的网页。

—- 搜索引擎的实现机制一般有两种,一种是通过手工方式对网页进行索引,比如yahoo的网页是通过手工分类的方式实现的,它的缺点是Web的覆盖率比较低,同时不能保证最新的信息。查询匹配是通过用户写入的关键字和网页的描述和标题来进行匹配,而不是通过全文的匹配进行的。第二种是对网页进行自动的索引,象AltaVista则是完全通过自动索引实现的。这种能实现自动的文档分类,实际上采用了信息提取的技术。但是在分类准确性上可能不如手工分类。

—- 搜索引擎一般都有一个Robot定期的访问一些站点,来检查这些站点的变化,同时查找新的站点。一般站点有一个robot.txt文件用来说明服务器不希望Robot访问的区域,Robot 都必须遵守这个规定。如果是自动索引的话,Robot在得到页面以后,需要对该页面根据其内容进行索引,根据它的关键字的情况把它归到某一类中。页面的信息是通过元数据的形式保存的,典型的元数据包括标题、IP地址、一个该页面的简要的介绍,关键字或者是索引短语、文件的大小和最后的更新的日期。尽管元数据有一定的标准,但是很多站点都采用自己的模板。文档提取机制和索引策略对Web搜索引擎的有效性有很大的关系。高级的搜索选项一般包括:布尔方法或者是短语匹配和自然语言处理。一个查询所产生的结果按照提取机制被分成不同的等级提交给用户。最相关的放在最前面。每一个提取出来的文档的元数据被显示给用户。同时包括该文档所在的URL地址。

—- 另外有一些关于某一个主题的专门的引擎,它们只对某一个主题的内容进行搜索和处理,这样信息的取全率和精度相对就比较高。

—- 同时,有一类搜索引擎,它本身不用Robot去定期的采集网页。象SavvySearch 和 MetaCrawler是通过向多个搜索引擎同时发出询问并对结果进行综合返回给用户实现搜索功能。当然实际上象SavvySearch能够对各个搜索引擎的功能进行分析和比较,根据不同的用户查询提交给不同的搜索引擎进行处理,当然用户自己也可以指定利用哪一个搜索引擎。

—- 一个优秀的搜索引擎必须处理以下几个问题:1 网页的分类2 自然语言的处理3 搜索策略的调度和协作 4 面向特定用户的搜索。所以很多搜索引擎不同程度的使用了一些人工智能的技术来解决这些方面的问题。

—- 二、网络Spider的实现描述

—- 现在有很多文章对Web引擎做了大量的介绍和分析,但是很少有对它们的实现做一个详细的描述,这里我们主要来介绍一个具有基本功能的Web引擎的实现。本文,我们以类C++语言的形式来描述Web引擎如何采集网页并存放到数据库中的过程。同时描述了如何根据用户输入的关键字查询数据库并得到相关网页的过程。

—- 2.1数据库结构

—- 首先,我们要建立一个数据库表用来存放我们得到的网页。这里一般需要建立如下的表:

—- 1.字典表的建立,事实上这里是用文档中有意义的单词和它们的出现频率来代表一个文档。

—- 该表(WordDictionaryTbl)主要要包括三个字段,主要是用来存放和一个网页相关的单词的情况

    url_id    对每一个URL的唯一的ID号
    word      该URL中的经过stem的单词
    intag    该单词在该网页中的出现的次数

—- 2.存储每一个URL信息的表

—- 该表(URLTbl)中主要的关键字段有:

  rec_id        每一条记录的唯一的ID号
  status    得到该URL内容的状态,比如HTTP_STATUS_TIMEOUT表示
            下载网页的最大允许超时
  url        URL的字符串名称
  content_type      内容的类型
  last_modified    最新的更改时间
  title            该URL的标题
  docsize          该URL的文件的尺寸
  last_index_time  最近一次索引的时间
  next_index_time  下一次索引的时间
  tag    对于网页,用来表示它的类型,比如:是text,或者是html,
                    或者是图片等等
  hops              得到文件时候的曾经失败的次数
  keywords          对于网页,和该网页相关的关键字
  description      对于网页,指网页的内容的描述
  lang              文档所使用的语言

—- 3.因为网页中有很多单词是一些介词和语气助词或者是非常常用的常用词,它们本身没有多少意义。比如:英语中的about,in,at,we,this等等。中文中的如”和”,”一起”,”关于”等等。我们统一的把它们称为停止词(stop word)。所以我们要建立一个表,来包括所有这些停止词。该表(StopWordTbl)主要有两个字段。
word char(32)    表示那些停止词
lang char(2)      表示所使用的语言

—- 4.我们要建立一个关于robot的表,我们在前面说过,所有的网站一般都有一个robot.txt文件用来表示网络上的robot可以访问的权限。该表(RobotTbl)主要有以下字段。
    hostinfo          Web站点主机的信息
    path              不允许robot访问的目录

—- 5.建立我们需要屏蔽的那些网页(比如一些内容不健康的或者没有必要去搜索的站点)的一张表(ForbiddenWWWTbl),主要的字段就是网页的URL。

—- 6.另外我们需要建立一个我们所要得到的文件类型的表(FileTypeTbl),比如,对于一个简单的Web搜索引擎,我们可能只需要得到后缀为.html,htm,.shtml和txt的类型文件。其他的我们只是简单的忽略它们。主要的字段就是文件的类型和说明。

—- 其中关于停止词的表的内容是我们要实现要根据各种语言的统计结果,把那些意义不大的单词放进去。关于文档单词、URL和Robot的表的内容都是在获取Web网页的时候动态增加记录的。

—- 2.2 具体网页获取算法描述

—- 具体的网页的获取步骤是这样的:

—- 我们可以设定我们的搜索程序最大可以开的线程的数目,然后这些线程可以同时在网上进行搜索,它们根据数据库中已有的关于网页的信息,找出那些需要更新的网页(如何判断哪些网页需要更新是一个值得研究的过程,现在有很多启发式和智能的算法,基本上是基于统计规律进行建模。最简单的当然是设定一个时间范围,在某个时间范围以前的网页被重新去搜索一遍),然后判断那些网页是否在屏蔽表中,如果是的话,就从关于URL的表中删除该条记录。否则,我们就到相应的WWW站点去得到URL指定的文件(这里需要注意的是根据不同的URL的特点,需要使用不同的协议,比如对于FTP站点要采用FTP协议,对于HTTP站点要采用HTTP协议,新闻站点要采用NNTP协议等等)事实上,我们先得到关于该网页的头信息,如果该网页的最新修改时间和我们最近提取的时间是一样的话,表示该网页内容没有任何更新,则我们就不必去得到它的内容,只需要修改最近一次更新它的时间为当前的时间就可以了。如果该网页最近做了修改,我们就要得到该网页,并对它的内容进行分析,主要要包括和它相关的链接,把它们加到相应的数据库中,同时判断网页所包含的各种其他的文件,如文本文件、图形文件、声音文件和其他多媒体文件是否是我们所需要的文件,如果是的话,就把它加到我们响应的数据库中。同时要根据网页的内容提取所有的有意义的单词和它们的出现的次数,放到相应的数据库中。为了更好的描述这个过程,我们来看跟这个过程相关的主要的几个对象和数据结构。对象主要是针对三个层次来讲的。第一层是针对WWW服务器,第二层是针对每一个页面,第三层是针对每一个页面的全文的索引。

—- 2.3 和实现相关的主要类对象和功能描述下面的结构是针对一个站点来说的。

    Class  CServer {
    主要的属性有:
    char *url;            //WWW站点的URL名称
    char *proxy;          //使用的代理的名称
    char *basic_auth;      //进行基本的HTTP认证
    int  proxy_port;      //代理的端口号
    int  period;          //再次索引的周期
    int  net_errors;      //网络连接不通的次数
    int  max_net_errors;  //可以允许的最大的网络错误
    int  read_timeout;    //下载文件允许的最大的延迟
    int  maxhops;          //表示URL可以最大跳转的深度
    int  userobots;        //是否遵守robot.txt中的约定
    int  bodyweight;  // 在< body >….< /body >之间的单词的权重
    int  titleweight; // 在< title >….< /title >之间的单词的权重
    int  urlweight;  // 在文档的URL中的单词的权重
    int descweight;//在    < META
NAME=”Description”        Content=”…” >之间单词的权重
    int  keywordweight; //在< META NAME=”Keywords” Content=”…” >
  之间的单词的权重

—- 主要方法有:
FindServer();//用来查找该服务器是否存在并可以连接
FillDefaultAttribute() //用来针对所有的WWW服务器填写默认的属};

以上的对象中的成员变量是和一个站点相关的参数的设置,我们对所有的站点有一个默认的设置,但是可以对某些站点做一些特殊的设置。这些设置可以在配置文件中设定。
—- 下面是关于文档的结构的主要的数据成员:

Class CNetDocument
    主要属性有:
    int    url_id; //该URL的ID号
    int    status;  //获取该文档时候的状态
    int    size;  //文档的尺寸
int    tag;  //和该文档相关的标签,表示该文档是
HTML,TEXT或者是其他类型
    int    hops;    //URL跳转的次数
    char    *url; //和该文档相关的URL的名称
    char    *content_type;      //该内容的类型
    char    *last_modified;    //最近一次的更新时间
    char    *title;            //该文档的标题
    char    *last_index_time;  //上次索引的时间
    char    *next_index_time;  //下次索引的时间
    char    *keywords;          //该文档中的关键字
    char    *description;      //该文档的描述

  主要方法有:
  FillDocInfo(…) //根据数据库,得到该文档相关信息
  AddHerf(…)    //加入网页中存在的新的链接的网址
  DeleteURL(…)  //删除一个存在的网址
  CanGetThisURL(…) //根据配置决定是否去得到该网页
  //下面三个方法是根据不同的URL,用不同的协议去获得文档
  NNTPGet(…)      
  FTPGet(….)
  HTTPGet(….)
  ParseHead(…)  //如果是HTTP协议得到的话,分析头信息
  ParseMainBody(…)    //对获得的文档的主体进行分析
  ServerResponseType (….)  //得到服务器端的响应消息
  UpdateURLDB(….)  //更新的数据入库
} ;

—- 事实上,我们在要提取一个网页的时候,都要建立一个CNetDocument对象,然后再对这个网页进行分析的时候,把相关的内容放到这个CNetDocument的成员变量里面。下面是关于页面全文索引的结构的主要数据成员:
Class CIndexer {
主要属性有:
  char    *url;      //我们要处理的文档相关的URL的名称
  int mwords;      //  我们事先设定的一个网页的最大的单词数目
    int nwords;          // 实际的得到的单词的数目
    int swords;          // 我们已经排序的单词的数目
    WORD *Word;      //所有单词的内容
    char *buf;      //我们为文档所分配的空间
主要方法有:
  InitIndexer(…)    //进行初始设置和分配
  ParseGetFile(…)  //对得到的网页进行全文索引
  AddWord(…)    //把网页的可以索引的单词加到Word数组中去
  InToDB(….)    //关于网页全文索引的信息入库
};

—- 进行网页提取前,我们要建立一个CIndexer对象,它主要是用来对网页进行全文的索引。一般来说我们只对两种类型的URL进行全文索引,一个是text/html,另外一个是text/plain。其中WORD的数据结构如下:
        typedef struct word_struct {
    int count;  //该单词出现的次数
    int code;  //该单词的正常的形式,
比如单词可能为 encouraging,它的正常的形式应该为
encourage,这其实是一种对单词的stem。
即我们只取单词的主干部分。
    char *word;  //该单词的内容
} WORD;

—- 以下的结构是和网页中的一些链接的对象相关的一个数据结构
    typedef struct href_struct {
    char *href;    //该链接的名称
    int hops;      //发生的跳转次数
    int stored;    //是否已经存储到数据库中
} HREF;
  

—- 所有需要更新的和新产生的URL都被放到这个结构中,当它的数量超过一定的范围以后,被一次性的存入数据库。
—- 关于URL的一个数据结构如下:

typedef struct url {
char *schema; //表示该URL是通过什么协议得到的,比如HTTP,
              FTP,NNTP等。
char *specific;    //主机的名称加上路径
char *hostinfo;    //主机的名称加上相关的协议端口
char *hostname;    //主机的名称
char *path;        //在主机的具体的路径
char *filename;    //文件的名称
char *anchor;      //相关的anchor
int  port;        //协议相关的端口
} URL;

—- 这是针对URL的一些相关的属性的描述的一个数据结构。事实上在数据库中,我们存储的只是对网页的描述和对一些文本和HTML页面的关键词的索引信息。我们并不存储网页的实际的内容。
—- 三、用户查询实现描述

—- 关于对用户提交的查询请求的实现分析:

—- 用户想要查询某一方面的信息一般都是通过提供和该领域相关的几个关键字来进行的。

—- 我们来看一下关于用户查询的相关的数据结构和类:

—- 下面是一个关于单词和它的权值的基本结构:

  typedef struct word_weight_pair
    {
      char word[WORD_LEN];
      int weight;
    }word_weight_pair;
   

—- 下面的类主要是用来对用户的查询进行处理和分析:
    Class CUserQuery
    {
char m_UserQuery[MAX_QUERYLEN];  //用户的查询表达式
CPtrArray word_weight_col;
//是关于结构word_weight_pair的动态数组
int m_maxReturnSum;  //用户希望返回的最多的网页数
int search_mode;
CObArray m_returnDoc;  //是关于CNetDocument对象的一个动态数组
NormalizeWord(char* OneWord);  //对单词进行归整化,即Stem.
Find(char* odbcName);  //进行数据库查找和匹配
};

—- 系统实现的基本的步骤如下:

—- 1.对用户输入的查询表达式进行分析。事实上,我们在前面的Spider搜索过程中对文档的表示是通过关键字形式描述的,每一个文档可以表示为这样的一个集合

    其中 ::=< 单词或短语名称 >< 单词或短语的权值 >

—- 实际上就是采用矢量空间的表示方法来表示的文档。

—- 我们对用户输入的查询表达式也采用矢量空间的表示方法。我们认为用户输入的关键字的顺序代表了它的重要性的程度,所以对于位置靠前的单词有相对比较高的优先级,同时我们对所有的内容以短语或者是单词为最小原子,进行Stem操作,即象前面所提到的:比如单词Encouraging就转化成Encourage的格式。然后去掉那些Stop Word,比如is ,as等等的单词,这些单词存放在StopWordTbl表中。 然后把所有归整化后的内容放入动态数组word_weight_col中去。

—- 2.对于动态数组word_weight_col中的每一个元素,即结构word_weight_pair(包括单词和该单词的权重),我们从表WordDictionaryTbl中可以找到和这些单词相关的记录,这些记录应该是包括了所有的在word_weight_col中的单词。

—- 进行网页是否和查询相匹配的计算。匹配计算的过程如下:首先我们对所有的记录按URL地址进行排序。因为可能好几条记录对应的是一个URL,然后对每一个网页进行打分,每一条记录的单词权值为INITSCORE*WEIGHT+(TOTALTIMES-1)*WEIGHT* INCREMENT。其中INITSCORE为每一个单词的基准分数,TOTALTIMES为该单词在网页中的出现的次数,WEIGHT是该单词在不同的内容段出现有不同的权值(比如在KEYWORD段,或者是标题段,或者是内容段等等)。INCREMENT是该单词每多出现一次所增加的分数。

—- 3.根据用户指定的m_maxReturnSum,显示匹配程度最高的前m_maxReturnSum页。

—- 四、结束语

—- 我们利用上面所讨论的机制,在WINDOWS NT操作系统下,用VC++和SQL SERVER实现了一个Web搜索引擎的网页搜集过程。在建立了一个基本的搜索引擎的框架以后,我们可以基于这个框架,实现一些我们自己设计的算法,比如如何更好的进行Spider的调度,如何更好的进行文档的归类,如何更好的理解用户的查询,用来使Web搜索引擎具有更好的智能性和个性化的特点。