asp html解析,自己写的,通过测试。

    最近写一个采集程序,然后就想到了通用分析网页再采集数据的方法,通过几天的摸索终于写出来了,与博客园的各位分享。

    欢迎测试,欢迎指正,欢迎评论。

  1 <%  

  2 ' asp html解析

  3  '  
  4  '  by 吴烈 xWorker.cn
  5  '  保留所有权利。不得用于商业用途,只能作为个人学习参考。
  6  '  
  7  ' ===========================================================================================
  8  ' ===========================================================================================
  9  ' ===============                        处理函数                     ==============================
 10 
 11  ' --------------------------------------------
 12  '  清除注释
 13  function  clearAnnotate(str)
 14       dim  re
 15       set  re  =   New  RegExp
 16      re.Global  =   True
 17      re.IgnoreCase  =   True
 18      re.Pattern  =   " \<!--.*--> "
 19      clearAnnotate  =  re.Replace(str, ""
 20  end function
 21 
 22  ' --------------------------------------------
 23  '  字符串转换成单字数组
 24 
 25  function  string2CharArray(str)
 26      markDoubleChar  =   false   '  用来标识处理双字节
 27      nIndex  =   0   '  有效字符编号   
 28      n  =   0   '  双字节数目
 29       for  i  =   1   to   len (str)
 30          chrA  =   mid (str, i,  1 )
 31           if   Asc (chrA)  <   0   or   Asc (chrA)  >   255   then
 32               '  写入双字节
 33               redim  preserve sChar(nIndex  +   1 )
 34              sChar(nIndex)  =   Mid (str, i,  1 )
 35              
 36               '  写入双字节标识
 37               redim  preserve tChar(nIndex  +   1 )
 38              tChar(nIndex)  =   2
 39              
 40               '  增长索引号
 41              nIndex  =  nIndex  +   1
 42              
 43               ' 标识中文
 44              n  =  n  +   1
 45           else
 46               '  写入单字节
 47               redim  preserve sChar(nIndex  +   1 )
 48              sChar(nIndex)  =   Mid (str, i,  1 )
 49              
 50               '  写入单字节标识
 51               redim  preserve tChar(nIndex  +   1 )
 52              tChar(nIndex)  =   1
 53              
 54               '  增长索引号
 55              nIndex  =  nIndex  +   1
 56           end   if
 57       next
 58      
 59       ' ==========================================================================================================
 60       '  调试输出
 61       if  bDEBUG  then
 62       '  输出调试
 63      response.write  " sChar个数: "   &   ubound (sChar)  &   " <br /> "
 64      response.write  " 中文个数: "   &  n  &   " <br /> "
 65           for  i  =   0   to  ( ubound (sChar)  -   1 '  参见注意1
 66              response.write  " tChar( "   &  i  &   " )       字节数:  "   &  tChar(i)  &   "     |   字符:  "   &  sChar(i)  &   "     |   Acsii编码十进制:  "   &   Asc (sChar(i))  &   " <br /> "   &  vbCrlf
 67           next
 68       end   if
 69      
 70  end function
 71 
 72  ' --------------------------------------------
 73  '  解析html, 生成多个有关系的数组
 74  function  htmlParse()
 75      m  = 0
 76       do
 77          ch  =  GetCurrentChar()
 78           ' 开始判断
 79           if  ch  =   " < "   then
 80              ch  =  getNextChar()
 81              ascCh  =   Asc (ch)
 82               if  (ascCh  >=   Asc ( " A " ))  and  (ascCh  <=   Asc ( " z " ))  then
 83                   '  这样才是开始标签  <div
 84                   if  newNode()  <>   0   then   ' 记录开始点, 这是"<"的位置
 85                       '  出错了
 86                   end   if
 87               end   if
 88           elseif  ch  =   " / "   then
 89              ch  =  getNextChar()
 90              ascCh  =   Asc (ch)
 91               if  (ascCh  >=   Asc ( " A " ))  and  (ascCh  <=   Asc ( " z " ))  then
 92                   '  这样才是结束标签  /div>
 93                   '  注意: 不能排除text/css
 94                   if  closeNode()  <>   0   then   ' 记录开始点, 这是"/"的位置
 95                       '  出错了
 96                   end   if
 97               end   if
 98           else
 99               '  在创建和关闭过程中自动获取标签内部文字
100           end   if
101          m  =  m  +   1
102       loop   while  moveNext()
103      
104      
105      
106       ' ==================================================================================================
107       '  调试输出
108       if  bDEBUG  then
109       '  输出调试    
110      response.write  " 循环 "   &  m  &   " 次<br /> "   &  vbCrLf
111       end   if
112       ' ==========================================================================================
113       '  调试输出
114       if   not  bDEBUG  then
115      response.write  " <br /> "   &  vbCrLf  &   " tagInfo Array: "   &   " <br /> "   &  vbCrLf  &   " <br /> "   &  vbCrLf
116           for  i  =   0   to  ( ubound (tagInfo)  -   1 )
117              
118              response.write i  &   " : tagInfo( "   &  i   &   " ) 自动编号:  "   &  tagInfo(i)( 0 &   "  标签名称:  "   &  tagInfo(i)( 1 &   "  标签类型:  " &  tagInfo(i)( 2 &   "  层次号:  " &  tagInfo(i)( 3 &   "  标签文字1:  " &  tagInfo(i)( 4 &   "  标签文字2:  "   &  tagInfo(i)( 5 &   " <br /> "   &  vbCrLf
119           next
120       end   if
121   
122  end function
123 
124  ' --------------------------------------------
125  ' 获取当前单字
126  function  getCurrentChar()
127      getCurrentChar  =  sChar(index)
128  end function
129 
130  ' --------------------------------------------
131  ' 获取下一个单字
132  function  getNextChar()
133      n  =  index  +   1
134      getNextChar  =  sChar(n)
135  end function
136 
137  ' --------------------------------------------
138  ' 获取单字
139  function  getChar(nIndex)
140      getChar  =  sChar(nIndex)
141  end function
142 
143  ' --------------------------------------------
144  '  移动标识
145  function  moveNext()
146       if  index  <  nCharCount  then
147          index  =  index  +   1
148          moveNext  =   true
149       else
150          moveNext  =   false
151       end   if
152  end function
153 
154  ' --------------------------------------------
155  '  移动标识到 nIndex
156  function  moveTo(nIndex)
157       if  nIndex  <  nCharCount  then
158          index  =  nIndex
159          moveTo  =   true
160       else
161          moveTo  =   false
162       end   if
163  end function
164 
165  ' --------------------------------------------
166  '  是否是尾部
167  function  isEOF()
168       if  index  <  nCharCount  then
169          isEOF  =   true
170       else
171          isEOF  =   false
172       end   if
173  end function
174 
175  ' --------------------------------------------
176  '  时候是双字节
177  function  isDoubleChar()
178       if  tChar(index)  =   2   then
179          isDoubleChar  =   true
180       else
181          isDoubleChar  =   false
182       end   if
183      
184       ' ===================================================================================================
185       '  调试输出
186      sDEBUG  =   true
187       if  sDEBUG  then
188       '  输出调试    
189      response.write  " tChar( "   &  index  &   " ) 字节数: "   &  tChar(index)  &   " <br /> "   &  vbCrLf
190       end   if
191  end function
192 
193  ' --------------------------------------------
194  '  新建一个节点,并返回详细信息
195  function  newNode()
196       '  新建标签
197      newTagReturn  =  newTag()
198       if   0   <>  newTagReturn  then
199          newNode  =  newTagReturn
200           '  第一步出错,
201       end   if    
202  end function
203 
204  ' --------------------------------------------
205  '  关闭一个节点,并返回详细信息
206  function  closeNode()
207       '  新建标签
208      closeTagReturn  =  closeTag()
209       if   0   <>  closeTagReturn  then
210          closeNode  =  closeTagReturn
211           '  第一步出错,不是结束标签
212       end   if
213  end function
214 
215  ' --------------------------------------------
216  '  新建一个标签,并返回详细信息
217  function  newTag()
218       '  1 检查是否存在标签
219       '  2 存储标签,并且移动标识到标签前部的末端 <td width="311" height="80" background="../images/title/330400.gif">
220       '  3 标识当前父标签
221       '  获取标签名称
222      tagName  =  getTagNameL()
223      tagNameLen  =   Len (tagName)
224       if  isInTagNameArrayA(tagName)  then   '  需配对的标签
225           '  移动标识到标签左边末端
226          moveToTagLeftSide()
227          
228           '  写入tagInfo
229           redim  preserve tagInfo(tagInfoIndex  +   1 )
230          tagInfo(tagInfoIndex)  =   Array (tagInfoIndex, tagName,  " A " , nodeUin, getTagTextL(),  "" )
231           '  0   自动编号
232           '  1   标签名称
233           '  2   标签类型 A 或者 B
234           '  3   层次号
235           '  4   标签文字1
236           '  5   标签文字2
237          tagInfoIndex  =  tagInfoIndex  +   1
238          
239           '  写入 tempList 临时队列,一边配对 
240           redim  preserve tempList(tempListIndex  +   1 )
241          tempList(tempListIndex)  =   Array (tagInfoIndex  -   1 , tagName)
242           '    标签编号
243           '    标签名称
244          tempListIndex  =  tempListIndex  +   1
245          
246           '  层结构加1
247          nodeUin  =  nodeUin  +   1
248       elseif  isInTagNameArrayB(tagName)  then   '  不需配对的标签
249           '  移动标识到标签左边末端
250          moveToTagLeftSide()
251          
252           '  写入tagInfo
253           redim  preserve tagInfo(tagInfoIndex  +   1 )
254          tagInfo(tagInfoIndex)  =   Array (tagInfoIndex, tagName,  " B " , nodeUin,  "" "" )
255           ' 0   自动编号
256           ' 1   标签名称
257           ' 2   标签类型 A 或者 B
258           ' 3   层次号
259           ' 4   标签文字1
260           ' 5   标签文字2
261          tagInfoIndex  =  tagInfoIndex  +   1
262          
263           '  层结构不变
264       else
265           '  标签名不存在
266          response.Write  " 标签名:  "   &  tagName  &   "  不存在 <br /> "   &  vbCrLf
267       end   if
268      
269       '  返回
270      newTag  =   0
271      
272      
273       ' ==========================================================================================
274       '  调试输出
275       if  bDEBUG  then
276          response.write index   &   "  :  "   &  tagName  &   "  len:  "   &   Len (tagName)  &   " <br /> "   &  vbCrLf
277          i  =  tagInfoIndex  -   1
278          response.write  "  tagInfo( "   &  i   &   " ) 自动编号:  "   &  tagInfo(i)( 0 &   "  标签名称:  "   &  tagInfo(i)( 1 &   "  标签类型:  " &  tagInfo(i)( 2 &   "  父节点编号:  " &  tagInfo(i)( 3 &   "  标签文字1:  " &  tagInfo(i)( 4 &   "  标签文字2:  "   &  tagInfo(i)( 5 &   " <br /> "   &  vbCrLf
279       end   if
280  end function
281 
282  ' --------------------------------------------
283  '  关闭一个标签,并返回详细信息
284  function  closeTag()
285       '  1 检查是否存在标签
286       '  2 存储标签,并且移动标识到标签前部的末端 <td width="311" height="80" background="../images/title/330400.gif">
287       '  3 标识当前父标签
288 
289       '  没有A标签
290       if  nodeUin  =   0   then
291          closeTag  =   2
292           exit   function
293       end   if
294       '  标签名称
295      tagNameR  =  getTagNameR()
296       '  排除text/css的情况,再次确认是否是结束标签
297       if   not  (isInTagNameArrayA(tagNameR)  or  isInTagNameArrayB(tagNameR))  then
298          closeTag  =   1
299           exit   function
300       end   if
301       '  获得标签内部右边的文字
302      tagTextR  =  getTagTextR()
303       '  移动标识到末端 当前/ 移动到 >  /div>
304      moveTo(index  +   Len (tagNameR)  +   1 )
305       '  获取标签id
306      tagId  =   0
307       for  i  =  ( ubound (tempList)  -   1 to   0  step  - 1
308           if  tempList(i)( 1 =  tagNameR  then
309              tagId  =  tempList(i)( 0 )
310               '  更改 tempList 记录
311              tempList(i)( 1 =   " NullTagName "
312               '  减小层结构数
313              nodeUin  =  nodeUin  -   1
314               exit   for
315           end   if
316       next
317      
318       '  比对左边文本,并写入
319       if  tagInfo(tagId)( 4 <>  tagTextR  then
320         tagInfo(tagId)( 5 =  tagTextR
321       else
322         tagInfo(tagId)( 5 =   ""
323       end   if
324      
325      
326  end function
327 
328  ' --------------------------------------------
329  '  获取一个标签名称(左边)
330  '  标识位置: <
331  function  getTagNameL()
332      n  =   0
333      tTagName  =   ""
334       do   while  (isEOF()  and  n  <   9 )
335          ch  =  getChar(index  +  n  +   1 )
336           if  ch  =   Chr ( 32 or   ch  =   Chr ( 62 then
337               for  i  =   1   to  n
338                  tTagName  =  tTagName  &  sChar(index  +  i)
339               next
340               exit   do
341           end   if
342          n  =  n  +   1
343       loop
344      getTagNameL  =  tTagName
345  end function
346 
347  ' --------------------------------------------
348  '  获取一个标签名称(右边)
349  '  标识位置: /
350  function  getTagNameR()
351      n  =   0
352      tTagName  =   ""
353       do   while  (isEOF()  and  n  <   9 )
354          ch  =  getChar(index  +  n  +   1 )
355           if  ch  =   Chr ( 62 then
356               for  i  =   1   to  n
357                  tTagName  =  tTagName  &  sChar(index  +  i)
358               next
359               exit   do
360           end   if
361          n  =  n  +   1
362       loop
363      getTagNameR  =  tTagName
364  end function
365 
366  ' --------------------------------------------
367  '  移动标识到标签左边末端 
368  '  当前标识: >
369  function  moveToTagLeftSide()
370      n  =   0
371       do   while  isEOF()
372          ch  =  getChar(index  +  n  +   1 )
373           if  ch  =   " > "   then
374              moveTo(index  +  n  +   1 )
375              moveToTagLeftSide  =   true
376               exit   function
377           end   if
378          n  =  n  +   1
379       loop
380       '
381      moveToTagLeftSide  =   false
382  end function
383 
384  ' --------------------------------------------
385  '  是否是A标签(有配对的标签)
386  function  isInTagNameArrayA(sTagName)
387       for   each  tagName in tagNameArrayA
388           if  tagName  =  sTagName  then
389               '  找到就返回
390              isInTagNameArrayA  =   true
391               exit   function
392           end   if
393       next
394       '  表示没有找到
395      isInTagNameArrayA  =   false
396  end function
397 
398  ' --------------------------------------------
399  '  是否是B标签(不需配对的标签)
400  function  isInTagNameArrayB(sTagName)
401       for   each  tagName in tagNameArrayB
402           if  tagName  =  sTagName  then
403               '  找到就返回
404              isInTagNameArrayB  =   true
405               exit   function
406           end   if
407       next
408       '  表示没有找到
409      isInTagNameArrayB  =   false
410  end function
411 
412  ' --------------------------------------------
413  '  获得标签内部左边的文本
414  function  getTagTextL()
415       '  此时标识已经是末端了
416      n  =   0
417      tTagText  =   ""
418       do   while  isEOF()
419          ch  =  getChar(index  +  n  +   1 )
420           if  ch  =   Chr ( 60 then
421               for  i  =   1   to  n
422                  tTagText  =  tTagText  &  sChar(index  +  i)
423               next
424               exit   do
425           end   if
426          n  =  n  +   1
427       loop
428      getTagTextL  =  tTagText
429  end function
430 
431  ' --------------------------------------------
432  '  获得标签内部右边的文本
433  function  getTagTextR()
434       '  此时标识已经是末端了
435      n  =   0
436      tTagText  =   ""
437       do   while  isEOF()
438          ch  =  getChar(index  -  n  -   1 )
439           if  ch  =   " > "   then
440               for  i  =  n  to   2  step  - 1
441                  tTagText  =  tTagText  &  sChar(index  -  i)
442               next
443               exit   do
444           end   if
445          n  =  n  +   1
446       loop
447      getTagTextR  =  tTagText
448  end function
449 
450  ' --------------------------------------------
451  '  是否是B标签()
452  function  isInTagrayB(sTagName)
453 
454  end function
455 
456  ' --------------------------------------------
457  '  是否是B标签()
458  function  isInTgNmeArrayB(sTagName)
459 
460  end function
461 
462  ' --------------------------------------------
463  '  是否是B标签()
464  function  isInTagameArayB(sTagName)
465 
466  end function
467 
468  ' --------------------------------------------
469  '  使用FSO读取文件内容的函数
470  function  FSOFileRead(filename) 
471       dim  objFSO, objCountFile, FiletempData 
472       set  objFSO  =  Server.CreateObject( " Scripting.FileSystemObject "
473       set  objCountFile  =  objFSO.OpenTextFile(Server.MapPath(filename),  1 true
474      FSOFileRead  =  objCountFile.ReadAll 
475      objCountFile.Close 
476       set  objCountFile  =   nothing  
477       set  objFSO  =   nothing  
478  end function  
479 
480 
481 
482 
483  ' ===========================================================================================
484  ' ===========================================================================================
485  ' =========================                          执行体                       ===============================
486  '  一些设置
487  bDEBUG  =   false
488 
489  '  注意这个文件
490  htmlStr  =  FSOFileRead( " test.html " )
491 
492  ' htmlStr = "<meta http-equiv=""Content-Type"" content=""text/html; charset=gb2312""><html xmlns=""http://www.w3.org/1999/xhtml""><html><head><meta http-equiv=""Content-Type"" content=""text/html; charset=gb2312""><title>朱自成的个人简历-路桥技术/隧道工程·工民建·土建工程师 | 12年工作经验 | 大专 | 路桥 嘉兴人才招聘网</title><meta NAME=""keywords"" content=""嘉兴人才网,嘉兴人才招聘网,嘉兴人才市场,嘉兴招聘网,嘉兴人才网,嘉兴人才招聘网-打造嘉兴最好的人才招聘网站  口碑铸就人气!,http://www.0573hr.com.cn""><meta name=""description"" content=""嘉兴人才网,嘉兴人才招聘网,嘉兴人才市场,嘉兴招聘网,嘉兴人才网,嘉兴人才招聘网-打造嘉兴最好的人才招聘网站  口碑铸就人气!,http://www.0573hr.com.cn"" ><link href=""images/grjl.css"" rel=""stylesheet"" type=""text/css""></head><body><table width=""991"" border=""0"" cellspacing=""0"" cellpadding=""0""><tr><td width=""311"" height=""80"" valign=""bottom"" background=""../images/title/330400.gif""><table width=""275""  border=""0"" align=""right"" cellpadding=""0"" cellspacing=""0""><tr><td width=""266"" height=""35"" class=w>求职<b>嘉兴人才招聘网</b>--打造嘉兴最好的人才招聘网站</td></tr></table></td></tr></table><div>name</div></body></html>"
493 
494  ' <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
495  ' <html xmlns="http://www.w3.org/1999/xhtml">
496  '    <html>
497  '        <head>
498  '            <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
499  '            <title>朱自成的个人简历-路桥技术/隧道工程·工民建·土建工程师 | 12年工作经验 | 大专 | 路桥 嘉兴人才招聘网</title>
500  '            <meta NAME="keywords" content="嘉兴人才网,嘉兴人才招聘网,嘉兴人才市场,嘉兴招聘网,嘉兴人才网,嘉兴人才招聘网-打造嘉兴最好的人才招聘网站  口碑铸就人气!,http://www.0573hr.com.cn">
501  '            <meta name="description" content="嘉兴人才网,嘉兴人才招聘网,嘉兴人才市场,嘉兴招聘网,嘉兴人才网,嘉兴人才招聘网-打造嘉兴最好的人才招聘网站  口碑铸就人气!,http://www.0573hr.com.cn" >
502  '            <link href="images/grjl.css" rel="stylesheet" type="text/css">
503  '        </head>
504  '        <body>
505  '            <table width="991" border="0" cellspacing="0" cellpadding="0">
506  '                <tr>
507  '                    <td width="311" height="80" valign="bottom" background="../images/title/330400.gif">
508  '                        <table width="275"  border="0" align="right" cellpadding="0" cellspacing="0">
509  '                            <tr>
510  '                                <td width="266" height="35" class=w>
511  '                                    求职
512  '                                    <b>
513  '                                        嘉兴人才招聘网
514  '                                    </b>
515  '                                    --打造嘉兴最好的人才招聘网站
516  '                                </td>
517  '                            </tr>
518  '                        </table>
519  '                    </td>
520  '                </tr>
521  '            </table>
522  '            <div>
523  '                name
524  '            </div>
525  '        </body>
526  '    </html>
527 
528  '  1 网页字符串预处理
529  '  --------------------------------------------------------------------------------------------------
530 
531  '  1.0   按行读取,清楚左边空格,再合并
532  tCharArray   =   split (htmlStr, vbCrLf)
533  htmlStr  =   ""
534  for  j  =   0   to   Ubound (tCharArray)
535      htmlStr  =  htmlStr  +   Trim (tCharArray(j))
536  next
537  '  全部转换成小写
538  htmlStr  =   LCase (htmlStr)
539  '  1.1   清除注释
540  htmlStr  =  clearAnnotate(htmlStr)
541 
542  response.write  " 经过处理后的htmlStr文字个数:  "   &   Len (htmlStr)  &   " <br /> "   &  vbCrLf
543 
544  '  1.2   将字符串裁剪成单个字符,注意非英文的,并且记录是否是英文
545  dim  sChar()  '  字符串单字数组
546  dim  tChar()  '  记录单字是否为多字节
547  string2CharArray(htmlStr)  '  注意1: 这样最后下标的数组是空的
548 
549 
550  '  2 生成html标签树
551  '  --------------------------------------------------------------------------------------------------
552  index  =   0   '  当前单字下标标识
553  nCharCount  =   ubound (sChar)  -   1   '  字符数 (实际  + 1)
554  nCurrentFatherTag  =   0   '  当前父标签下标,用来处理 <A>文本段1<B>文本段2</B>文本段3</A> 这样的情况
555  lastTagType  =   " A "
556  ' 有配对的标签
557  tagNameArrayA  =   Array ( " html " " body " " head " " title " " p " " center " " pre " " div " " nobr " " wbr " " strong " " b " " em " " i " " tt " " u " " h1 " " h2 " " h3 " " h4 " "" " h5 " " h6 " " font " " basefont " " big " " small " " strike " " code " " kbd " " samp " " var " " cite " " blockquote " " dfn " " address " " sub " " sup " " ol " " ul " " li " " menu " " dir " " dl " " dt " " dd " " table " " caption " " tr " " td " " th " " form " " textarea " " input " " select " " option " " a " " frameset " " iframe " " noframes " " map " " marquee " " blink " " style " " span " )
558  ' 不需配对的标签
559  tagNameArrayB  =   Array ( " !doctype " " br " " hr " " input " " img " " base " " frame " " area " " bgsound " " meta " " link " )
560  dim  nodeInfo()
561  nodeInfoIndex  =   0
562  '  层次号
563  nodeUin  =   0
564  nodeInfoID  =   0
565  '    nodeInfo
566  '    自动编号
567  '    层数
568  '    子节点数
569  dim  tagInfo()
570  tagInfoIndex  =   0
571  tagInfoID  = 0
572  '    tagInfo
573  '    自动编号
574  '    标签名称
575  '    标签类型 A 或者 B
576  '    层次号
577  '    标签文字1
578  '    标签文字2
579  dim  tempList()
580  tempListID  =   0
581  tempListIndex  =   0
582  '    tempList 临时队列
583  '    标签名称
584 
585  '  解析html, 生成多个有关系的数组
586  htmlParse() 
587  % >


吴烈 倾情制作。

源代码下载 : http://files.cnblogs.com/wulie88/index.rar

转载于:https://www.cnblogs.com/wulie88/archive/2008/11/06/1328505.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值