百忙之中抽時間編寫了這個小程式,功能是:完美儲存整個網頁,包括:圖片、JS指令碼、CSS樣式,並且修改網頁源碼進行“本地化”。由於我火星了,竟然不知道瀏覽器內建這個功能,因此自己動手做了一個,雖然這個程式不大,但是涉及了三大難題(後文將會詳細講解)。
本來不打算髮布源碼的,既然瀏覽器有這個功能,那我就發布一下源碼以供大家學習!這個程式的效果和瀏覽器的效果是完全相同的!而且我對比了一下,擷取的js、css、圖片一個也不比瀏覽器擷取的少。大家可以參照這個去發揮:做一個網站整站下載器。當然資料庫你是絕對下不到的…..
使用說明:
1.填寫網頁地址然後點轉到,這時會啟用一鍵下載,載入網頁需要時間,沒載入完就點一鍵下載會有提示,盡量在網速比較好的時候使用!
2.下載完成後會在軟體目錄下產生一個以網頁標題為名稱的檔案夾,所有必須檔案都存放於此,其中以網頁標題為名稱的HTM檔案就是儲存的頁面,在沒有網路的情況下,雙擊查看的效果和在網路上看是一樣的!。
程式:
解決的難題:
1.判斷網頁載入完成。以前都是已知目的網頁,可以用“標誌法”判斷,但是在這個程式裡一切是未知的。所以必須用新方法,這裡用了HTML對象的Onload事件,結合webbrowser控制項完美實現判斷網頁載入完成,這是目前最安全、最準確、最可靠的方法!適用於一切環境。
判斷網頁載入完成一直是個非常頭疼的問題,至少在VB中是這樣。網上所說的方法基本上是不行的,好一點的是有時候行、有時候不行。現在我就貼出一個代碼,來終結這個問題
'引用“Microsoft HTML Object Library”Dim WithEvents page As HTMLWindow2 '注意要定義成全域的Private Sub WebBrowser1_NavigateComplete2(ByVal pDisp As Object, URL As Variant) Set page = Me.WebBrowser1.document.parentWindowEnd SubPrivate Sub page_onload() Debug.Print "載入完畢"End Sub
2.擷取網頁js和css。曾經看到很多人在豬八戒網發帖求人做程式,要求擷取網頁裡所有的js和css。其實這個並不難,百度一下我們可以發現javascript語言提供了這個介面。下面我就示範一下如何利用這個介面擷取。
首先用webbrowser控制項載入你要提取的網頁。
擷取js:
strBasicHTM = WebBrowser1.Document.documentElement.outerHTMLWebBrowser1.Navigate "javascript:str='<HTML><HEAD><BASE HREF="" ';str+=document.URL;str+='""></HEAD><BODY><br>\n';c=document.scripts;for(i=0;i<c.length;i++){o=c[i];if (o.src=='')continue;str+='<a href=""';str+=o.src;str+='"">';str+=o.src;str+='</a><br>\n';};str+='</BODY></HTML>';document.write(str);"While strBasicHTM = WebBrowser1.Document.documentElement.outerHTML '相等說明任務沒有執行完畢 DoEvents WendFor lngIndex = 0 To WebBrowser1.Document.links.length - 1 Debug.print WebBrowser1.Document.links.Item(lngIndex).innerText Next
結果圖:
通過上邊這段代碼webbrowser控制項裡顯示的就是該網頁中所有的js路徑,這個路徑就是網頁源碼中的路徑,不做任何修改。也就是說:如果源碼中寫的是絕對路徑,例如http:/www.xxx.com/x.js,那麼返回的就是絕對路徑http:/www.xxx.com/x.js;如果是相對路徑,例如/js/x.js,那麼返回的就是相對路徑/js/x.js。
最後用一個迴圈擷取webbrowser控制項中顯示的js路徑(其實就是擷取超連結文本)
還有就是注意一下上邊代碼中的strBasicHTM變數,這個變數是為了擷取webbrowser執行javascript語句前後的變化,以判斷是否執行完畢,使程式更加安全。
擷取css:
擷取css和擷取js過程一模一樣,只需要把
WebBrowser1.Navigate "javascript:str='<HTML><HEAD><BASE HREF="" ';str+=document.URL;str+='""></HEAD><BODY><br>\n';c=document.scripts;for(i=0;i<c.length;i++){o=c[i];if (o.src=='')continue;str+='<a href=""';str+=o.src;str+='"">';str+=o.src;str+='</a><br>\n';};str+='</BODY></HTML>';document.write(str);"
改成:
WebBrowser1.Navigate "javascript:str='<HTML><HEAD><BASE HREF="" ';str+=document.URL;str+='""></HEAD><BODY><br>\n';c=document.styleSheets;for(i=0;i<c.length;i++){o=c[i];if (o.src=='')continue;str+='<a href="" ';str+=o.href;str+='"">';str+=o.href;str+='</a><br>\n';};str+='</BODY></HTML>';document.write(str);"
最後說明一點:
javascript沒有直接提供擷取js檔案內容的介面,因此首先要對註冊表進行改造:運行regedit,定位到HKEY_CLASSES_ROOT\.js,在它下面增加兩個字串類型的值:
Content Type=application/x-javascript
PerceivedType=text
如果修改的時候不放心,可以參考HKEY_CLASSES_ROOT\.css的預設設定,它們只是Content Type的值不同。註冊表改造是一次性的工作,改完就不用再動。
用代碼改就是:
Dim lhwySet lhwy = CreateObject("wscript.shell")lhwy.regwrite "HKEY_CLASSES_ROOT\.js\Content Type", "application/x-javascript"lhwy.regwrite "HKEY_CLASSES_ROOT\.js\PerceivedType", "text"
3.判斷網頁編碼。先以GB編碼儲存,然後再讀取,如果和儲存之前不一樣,說明是UTF-8編碼,再用UTF-8編碼儲存。
用GB編碼儲存:
Open App.Path & "\xx.HTM" For Output As #1 Print #1, strHTMClose #1
用UTF-8編碼儲存:
'引用Microsoft ActiveX Data Objects 2.8 LibraryDim objStream As New ADODB.StreamDim str As String With objStream.Type = 2.Mode = 3.Open.Charset = "UTF-8".WriteText strHTM, adWriteLine.SaveToFile App.Path & "\xxHTM", adSaveCreateOverWrite.CloseEnd With
程式源碼