« Linux NAT + Squid + SARG 製作使用者上網記錄報表 | 首頁 | PHP 程式分享: 網頁計數器 »

2005年06月30日

VB6 HTML Parser 備忘

很久沒寫程式了真的會生疏... 對於 HTML Parser 這種 Case, 我還是選擇了熟悉的 VB6. 之前受夠了 Winsock 元件, 這次是用 wget 來抓網頁 :P 至於需登入才能瀏覽的網頁, 就用 Perl Socket 來做吧!

流程:

  1. Linux 電腦以 wget 取得網頁檔案後, 自動將該檔 FTP 至 VB 程式所在電腦 C:\temp 目錄
  2. VB 程式自網頁檔案取出所需表格內容, 將取出的資料儲存至 C:\temp\Parsed, 並將原始網頁檔案搬移至 C:\temp\Source

Linux Shell Script notes:

‧西元年轉民國年: $[`date +%Y`-1911]

西元年: 2005 輸出結果: 94

‧西元日期轉民國日期: "$[`date +%Y`-1911]/`date +%m`/`date +%d`"

西元日期: 30 June 2005 輸出結果: 94/06/30

wget -O output_filename "http://URL"

FTP Batch Scripts

VB6 Source Code notes:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
Sub Main()

    '使用 FileListBox 判斷檔案是否存在
    strPath = "C:\temp\"
    File1.Path = strPath
    If File1.ListCount > 0 Then
        strFilename = File1.List(0)
        strSourceFile = strPath & strFilename
        strParsedFile = strPath & "Parsed\" & strFilename
    Else
        Exit Sub
    End If

    '讀入網頁資料
    strData = ""
    Open strSourceFile For Input As #1
        Do Until EOF(1)
            Line Input #1, strStream
            strData = strData & strStream
        Loop
    Close #1

    '找到「目標」後, 往下尋找第二個「<tr」
    sFlag = InStr(strData, "目標")
    sFlag = InStr(sFlag, LCase(strData), "<tr")
    sFlag = InStr(sFlag + 1, LCase(strData), "<tr")
    eFlag = InStr(sFlag, LCase(strData), "</tr")
    oFlag = InStr(sFlag, LCase(strData), "</table")

    '讀取表格所有內容
    Open strParsedFile For Output As #1
    Do
        '讀出 <tr ... </tr 之間所有 <td 欄位內的資料
        strRow = Mid(strData, sFlag, eFlag - sFlag + 1)
        strCol = ""
        strArray = ""
        sF = 1
        eF = 1
        Do
            sF = InStr(eF, strRow, "<td")
            If sF = 0 Then Exit Do
            eF = InStr(sF, strRow, "</td")
            strCol = fn_getTD(Mid(strRow, sF, eF - sF + 1))
            strArray = strArray & strCol & ","
        Loop
        strArray = Left(strArray, Len(strArray) - 1) & vbCr
        Print #1, strArray
        sFlag = InStr(eFlag, LCase(strData), "<tr")
        eFlag = InStr(sFlag, LCase(strData), "</tr")
    Loop Until eFlag > oFlag
    Close #1

    Name strSourceFile As strPath & "Source\" & strFilename

End Sub

Function fn_getTD(strTD)

    '取得 TD 欄位內容
    sF = InStr(strTD, ">") + 1
    eF = InStrRev(strTD, "<")
    If sF < eF Then
        strTD = Mid(strTD, sF, eF - sF)
        If (InStr(strTD, ">") = 0 And InStr(strTD, "<") = 0) Then
            fn_getTD = Replace(Trim(strTD), ",", "")
        Else
            fn_getTD = fn_getTD(strTD)
        End If
    ElseIf sF = eF Then
        fn_getTD = ""
    ElseIf sF > eF Then
        fn_getTD = Replace(Trim(strTD), ",", "")
    End If

End Function

程式說明:

行號 說明
03~12 目的:

以 FileList Box 裡的檔案數量 (File1.ListCount) 來判斷檔案是否存在。

方法:

從 File1.ListCount 可得知某路徑裡的檔案數量。
目的路徑裡只會有兩種狀況:
無檔案 → 不處理;
有檔案 (每天只會有一個) → 進行處理, 處理完畢將檔案移動到別的路徑。

14~51 目的:

讀入 HTML 內容後, 取出目的表格 (Table) 內容。

方法:

指標移到起始點後, 每次取出一列 (<tr>...</tr>), 並將各欄 (<td>...</td>) 交給自定函數濾掉其中的 HTML Tag; 取出的各欄資料組成一列以逗號分隔的字串, 存入文字檔中。

53 移動檔案位置、變更檔案名稱, 語法為: Name "原路徑\原檔名" As "新路徑\新檔名"
57~75 目的:

以遞迴方式清除 <td> ... </td> 之間的 HTML Tag, 取出純資料內容。

方法:

從左邊數來第一個 " > " 為起點, 右邊數來第一個 " < " 為終點, 取出其間內容。

已知問題:

只能處理前後包夾的 HTML Tag, 如:

<td><div><p><span><font...>xxx</font></span></p></div></td>
處理結果: xxx

和單一 HTML Tag, 如:

<td>xxxxx<br>yyyyy</td>
處理結果: xxxxx<br>yyyyy

多個獨立 HTML Tag 會有問題, 如:

<td>xxxxx<br>yyyyy<br>zzzzz</td>
處理結果: yyyyy

遞迴處理基本精神:

function function_name(參數)

處理程序

if 處理完成 then

function_name = 結果值

else

function_name = function_name(處理過的參數)

end if

end function

Posted by Jamyy at 2005年06月30日 17:28

Trackback Pings

TrackBack URL for this entry:
http://cha.homeip.net/cgi-bin/mt/mt-tb.cgi/96

Comments

請程式寫作者,務必先寫出最重要的變數宣告,及初始化
由此可知 VB 對某些人來說並不適合...

Posted by: kio at 2007年11月22日 23:44