VB寫WebBrowser捕捉信息
|
admin
2013年11月28日 11:35
本文熱度 5027
|
在大多數(shù)情況下,上網(wǎng)沖浪是件令人愉快的事情。但若是數(shù)百上千的超鏈接擺在你面前,而你又不得不一一點(diǎn)擊這些鏈接、進(jìn)入相應(yīng)的網(wǎng)頁(yè)、手工篩選出每頁(yè)里你需要的信息、最后再將這些信息編進(jìn)數(shù)據(jù)庫(kù)中、....,你將做何感想?如果每天都從事這種繁雜、枯燥的工作會(huì)不會(huì)讓你發(fā)瘋? “自動(dòng)上網(wǎng)機(jī)器人”或許可救你出“苦海”:你可以喝著咖啡、聽(tīng)著音樂(lè)、看著“機(jī)器人”辛勤地替你工作,那感覺(jué)是不是棒極了! 本文結(jié)合實(shí)例詳盡討論了用VB實(shí)現(xiàn)“上網(wǎng)機(jī)器人”的技術(shù)細(xì)節(jié)。我們知道,搜集和下載資料是人們使用互聯(lián)網(wǎng)的最主要的目的之一,但有些信息資源過(guò)于龐大,用手工摘取的方法是困難的或根本就是行不通的。例如,你需要搜集歐洲進(jìn)口機(jī)械設(shè)備的公司名錄以便給他們發(fā)信邀請(qǐng)其參加博覽會(huì),在網(wǎng)上找到這些信息并不難,但出于數(shù)據(jù)安全等方面的考慮,幾乎所有提供類似信息的網(wǎng)站都沒(méi)有提供直接下載數(shù)據(jù)的功能。 要想搜集齊想要的數(shù)據(jù),唯一可用的方法就是一頁(yè)一頁(yè)地瀏覽每個(gè)公司的信息頁(yè),摘取其中有用的數(shù)據(jù)并存入數(shù)據(jù)庫(kù)。但當(dāng)公司總數(shù)超過(guò)數(shù)千時(shí),巨大的工作量會(huì)讓任何人望而卻步!其實(shí),這浩大的工作完全可以由程序來(lái)完成,因?yàn)檫@些任務(wù)完全是機(jī)械的重復(fù)性工作。而且,用程序完成比用手工要快得多。本文涉及的技術(shù)細(xì)節(jié)是通用的,即對(duì)實(shí)例程序稍加修改就可完成任何“自動(dòng)上網(wǎng)沖浪”任務(wù)。
自動(dòng)撥號(hào)上網(wǎng)、自動(dòng)處理中途掉線、任務(wù)完成后自動(dòng)掛斷,這些都是“上網(wǎng)機(jī)器人”的最基本的功能之一。它還能給你帶來(lái)明顯的經(jīng)濟(jì)回報(bào):如果你讓“機(jī)器人”在晚間至凌晨的上網(wǎng)費(fèi)優(yōu)惠期內(nèi)撥號(hào)上網(wǎng)去自動(dòng)沖浪,那真可稱得上是典型的“一石三鳥”----你睡覺(jué)、它工作、還省錢!有關(guān)這方面的細(xì)節(jié)將在本文的第三部分里討論。該部分提供了實(shí)現(xiàn)上述各功能的若干方法,并比較了這些方法各自的優(yōu)劣。
本文的第一和第二部分分別以兩個(gè)實(shí)例討論了自動(dòng)瀏覽的技術(shù)細(xì)節(jié):在網(wǎng)頁(yè)上的輸入?yún)^(qū)內(nèi)自動(dòng)填入數(shù)據(jù)以便完成諸如用戶登錄等的操作、自動(dòng)更新CheckBox、自動(dòng)選擇下拉式列表(ComboBox)的值、自動(dòng)點(diǎn)擊網(wǎng)頁(yè)上的按鈕、從網(wǎng)頁(yè)上精確提取有用的數(shù)據(jù)并存盤、將網(wǎng)頁(yè)上二維表(Table)內(nèi)的數(shù)據(jù)一一提取出來(lái)并轉(zhuǎn)換且存儲(chǔ)成可直接導(dǎo)入數(shù)據(jù)庫(kù)或 Excel的格式,以及控制瀏覽進(jìn)程的技巧等等。
第一部分 從網(wǎng)頁(yè)上精確提取數(shù)據(jù)
本部分的實(shí)例是:下載滬深兩市全部約1100家個(gè)股的基本信息及財(cái)務(wù)數(shù)據(jù)。若用手工操作,如上圖所示,需要在股票代碼區(qū)內(nèi)分別輸入1100個(gè)股票代碼,在下拉式列表(ComboBox)中分別選擇“個(gè)股資料”和“財(cái)務(wù)數(shù)據(jù)解讀”,算下來(lái)約是2200次操作!這樣的工作當(dāng)然是由程序來(lái)完成劃算得多。況且手工提取數(shù)據(jù)(先選中、再使用Ctrl+C拷貝)極容易出錯(cuò)(多選或漏選),又很費(fèi)眼神。
1. 在輸入?yún)^(qū)內(nèi)自動(dòng)填入數(shù)據(jù)
為使程序能高效地自動(dòng)瀏覽,需引入一些最基本的功能,如在輸入?yún)^(qū)內(nèi)自動(dòng)填入數(shù)據(jù)、自動(dòng)點(diǎn)擊按鈕等等。雖然用變換 URL地址的方法有時(shí)也能完成任務(wù),但往往過(guò)于費(fèi)力,尤其當(dāng)網(wǎng)頁(yè)上的輸入?yún)^(qū)較多時(shí)更是如此。
為了在輸入?yún)^(qū)內(nèi)輸入數(shù)據(jù),需要先搜索到該對(duì)象的名字,然后將該對(duì)象的值置為要填入的數(shù)據(jù)即可。搜索名字的工作可編程完成,亦可用 FrontPage輕松獲得。
2. 自動(dòng)在下拉式列表(ComboBox)中進(jìn)行選擇
同樣地,首先要獲得下拉式列表的名字。然后根據(jù)下拉式列表的元素總數(shù)(length屬性)在列表中搜索要設(shè)置的值(列表的 Options集合中元素的Text屬性),找到后,將該元素設(shè)為選中元素(元素的Selected屬性)。
3. 自動(dòng)點(diǎn)擊按鈕
對(duì)于按鈕來(lái)講,可根據(jù)其名字訪問(wèn),亦可根據(jù)其值訪問(wèn)。按鈕的值就是顯示在按鈕上的文字。一個(gè)按鈕可能沒(méi)有名字,但一定有值。本例的程序就是根據(jù)值來(lái)訪問(wèn)按鈕。執(zhí)行按鈕的 Click方法就相當(dāng)于點(diǎn)擊了該按鈕。
圖二中紅色箭頭所指即為程序自動(dòng)填入輸入框、自動(dòng)在ComboBox中選擇以及自動(dòng)點(diǎn)擊按鈕的情況。
4. 精確提取數(shù)據(jù)
僅將有用的數(shù)據(jù)存儲(chǔ)下來(lái)才是有意義的。必須研究網(wǎng)頁(yè),找出有效數(shù)據(jù)所在的Tag區(qū)(可用文本編輯器或 FrontPage),然后用該對(duì)象的innerText屬性獲得最終的文本。本例中要存儲(chǔ)的數(shù)據(jù)如下圖所示,其所用的Tag為“PRE”。
下面給出的是實(shí)例程序的完整代碼:
' 程序一:從網(wǎng)頁(yè)上精確提取數(shù)據(jù) ' ' 為運(yùn)行本程序,應(yīng)在“菜單->工程->部件”中添加“Microsoft Internet Controls” ' 并在“菜單->工程->引用”中添加“Microsoft HTML Object Library” ' ' 為了簡(jiǎn)潔,程序僅下載九只個(gè)股的基本信息 Option Explicit Private Const Form_ID = 1 Dim Code(9) As String Dim Current As Long Private Sub Form_Load() Form1.MousePointer = 11 ' 以下是個(gè)股代碼 ' 為了程序簡(jiǎn)潔,這里僅使用九只代碼。 ' 而在真實(shí)環(huán)境中,應(yīng)從數(shù)據(jù)文件中讀入全部個(gè)股代碼。 Code(0) = "600001": Code(1) = "600002": Code(2) = "600003" Code(3) = "600005": Code(4) = "600006": Code(5) = "600007" Code(6) = "600008": Code(7) = "600009": Code(8) = "600010" Current = 0 WebBrowser1.Navigate "www.stockstar.com.cn" ' 起始網(wǎng)址 End Sub
Private Sub WebBrowser1_DocumentComplete(ByValpDisp As Object, URL As Variant) Dim i, k Text2 = WebBrowser1.LocationURL ' 顯示當(dāng)前網(wǎng)址 ' 判斷當(dāng)前網(wǎng)頁(yè)是否全部調(diào)入完畢 If Not (pDisp Is WebBrowser1.Object) Then Exit Sub On Error Resume Next Select Case Text2 Case "http://www.stockstar.com.cn/home.htm" ' 當(dāng)進(jìn)入主頁(yè)面時(shí)執(zhí)行以下程序 For i = 0 To WebBrowser1.Document.Forms(Form_ID).length - 1 ' 找到代碼輸入框后填入個(gè)股代碼 If WebBrowser1.Document.Forms(Form_ID)(i).Name = "code" Then _ WebBrowser1.Document.Forms(Form_ID)(i).Value = Code(Current) ' 在下拉式列表中進(jìn)行選擇 If WebBrowser1.Document.Forms(Form_ID)(i).Name = "target" Then For k = 0 To WebBrowser1.Document.Forms(Form_ID)(i).length - 1 If WebBrowser1.Document.Forms(Form_ID)(i).Options(k).Text _ = "個(gè)股資料" Then WebBrowser1.Document.Forms(Form_ID)(i).Options(k).Selected = True Exit For End If Next k End If ' 點(diǎn)擊按鈕 If WebBrowser1.Document.Forms(Form_ID)(i).Value = " 查詢 " Then _ WebBrowser1.Document.Forms(Form_ID)(i).Click Next Case Else ' 當(dāng)進(jìn)入數(shù)據(jù)頁(yè)面時(shí)執(zhí)行以下程序 For i = 0 To WebBrowser1.Document.All.length - 1 If WebBrowser1.Document.All(i).tagName = "PRE" Then ' 精確提取數(shù)據(jù) Text1 = Text1 + Code(Current) + vbCrLf + _ WebBrowser1.Document.All(i).innerText + vbCrLf Exit For End If Next ' 數(shù)據(jù)存盤 Open "C:\Data2.Txt" For Append As #1 Print #1, Text1: Text1 = "": Close #1 ' 換下一只股票 Current = Current + 1 If Current >= 9 Then ' 上網(wǎng)任務(wù)完成后,應(yīng)在此調(diào)用自動(dòng)掛斷過(guò)程。 Form1.MousePointer = 0: MsgBox "Finished!": End End If ' 回退到主頁(yè)面,查詢下一只股票的信息 WebBrowser1.GoBack End Select End Sub |
來(lái)源:肥菜刀的專欄
[NextPage]
第二部分 將網(wǎng)頁(yè)上的二維表導(dǎo)入數(shù)據(jù)庫(kù)
在上一部分中,我們討論了讓程序自動(dòng)在網(wǎng)上瀏覽并將所需的數(shù)據(jù)準(zhǔn)確、快速地存儲(chǔ)下來(lái)的方法?,F(xiàn)在,我們將迎接更大的挑戰(zhàn):將網(wǎng)頁(yè)上以表格形式存在的二維數(shù)據(jù)提取出來(lái),并存成可直接導(dǎo)入數(shù)據(jù)庫(kù)的“Microsoft Excel 逗號(hào)分隔值文件”(即.csv文件)。
用手工在網(wǎng)頁(yè)上直接提取類似上圖中所示的表格數(shù)據(jù)是非常困難的。如果這樣的表格有數(shù)十頁(yè)甚至上百頁(yè)之多,手工提取工作將是不可想象的,而且非常容易出錯(cuò)。
本部分的實(shí)例是:將滬深兩市全部約1100家個(gè)股的財(cái)務(wù)評(píng)分表數(shù)據(jù)(共54頁(yè),每頁(yè)20家,如上圖所示)快速、準(zhǔn)確地轉(zhuǎn)換成“.csv”文件。
1. 自動(dòng)設(shè)置CheckBox的值
由于只有注冊(cè)用戶才能訪問(wèn)上述財(cái)務(wù)評(píng)分表,因此實(shí)例程序首先演示了自動(dòng)注冊(cè)的功能。下圖顯示的是注冊(cè)前以及自動(dòng)注冊(cè)后的畫面。
我們?cè)谏弦徊糠种幸延懻摿俗詣?dòng)填寫輸入?yún)^(qū)以及自動(dòng)點(diǎn)擊按鈕等的方法。對(duì)于自動(dòng)設(shè)置CheckBox值,其方法完全類似:首先要搜索到該CheckBox的名字,然后將該對(duì)象的Checked屬性置為True或False即可。
2. 將網(wǎng)頁(yè)上的二維表導(dǎo)入數(shù)據(jù)庫(kù)
首先定義一個(gè)IHTMLElementCollection對(duì)象用于收集網(wǎng)頁(yè)上所有的 Table,然后用getElementsByTagName方法執(zhí)行收集工作:
Dim Tables AsIHTMLElementCollection Set Tables = WebBrowser1.Document.getElementsByTagName("Table") |
一個(gè)網(wǎng)頁(yè)上往往有多個(gè) Table。我們用HTMLTable對(duì)象來(lái)處理每個(gè)Table:
Dim Table1 AsHTMLTable For Each Table1 In Tables Next |
HTMLTable對(duì)象的innerText屬性記錄了整個(gè) Table的全部信息,包括字段名。因此我們可以根據(jù)字段名判斷出哪個(gè) Table是我們需要的。
為了逐行逐列地提取數(shù)據(jù),我們還需要HTMLTableRow對(duì)象和HTMLTableCell對(duì)象:
Dim Row AsHTMLTableRow, Cell As HTMLTableCell For i = 1 To Table1.rows.length - 1 ' 逐行處理 Set Row = Table1.rows(i) j = 0 For Each Cell In Row.cells ' 逐列處理 ' Row.cells(j).innerText即為當(dāng)前行及當(dāng)前列上的單元數(shù)據(jù) Text1 = Text1 + Trim(Row.cells(j).innerText) + "," j = j + 1 Next ' 一行處理完畢后,去除行尾的逗號(hào)并加上回車 Text1 = Left(Text1, Len(Text1) - 1) + vbCrLf Next |
至此,當(dāng)前網(wǎng)頁(yè)上的二維表已轉(zhuǎn)換成“.csv”格式。
3. 自動(dòng)瀏覽時(shí)的頁(yè)面控制技巧
我們從上個(gè)例子中就已經(jīng)清晰地看到,自動(dòng)瀏覽程序的主體是WebBrowser控件的DocumentComplete事件。只有在當(dāng)前頁(yè)面已被完全調(diào)入后,我們才能開(kāi)始對(duì)當(dāng)前頁(yè)面進(jìn)行數(shù)據(jù)處理,然后再根據(jù)當(dāng)前在哪個(gè)頁(yè)面來(lái)決定下一步的瀏覽方向。
需要指出的是,DocumentComplete事件的發(fā)生并不一定意味著當(dāng)前頁(yè)面已被全部調(diào)入。如果頁(yè)面上沒(méi)有其它子框架(frames),發(fā)生DocumentComplete事件即表明當(dāng)前頁(yè)面(即主框架)已完成調(diào)入;若頁(yè)面上有多個(gè)框架,則每個(gè)框架完成時(shí)都會(huì)發(fā)生DocumentComplete事件;當(dāng)所有子框架都完成后,主框架最后產(chǎn)生一次DocumentComplete事件。為了判斷出這最后一次DocumentComplete事件,需要比較每次事件發(fā)生時(shí)的對(duì)象(pDisp)是否是WebBrowser控件對(duì)象本身:
Private Sub WebBrowser1_DocumentComplete(ByValpDisp As Object, _ URL As Variant) If (pDisp Is WebBrowser1.Object) Then Debug.Print "Document is finished loading." End If End Sub |
下面是實(shí)例程序的完整代碼(運(yùn)行該程序可得到完整的1061行“.csv”格式的數(shù)據(jù),分別代表1061個(gè)上市公司的財(cái)務(wù)信息。該文件可直接導(dǎo)入Access數(shù)據(jù)庫(kù)或 Excel中。):
' 程序二:將網(wǎng)頁(yè)上的二維表導(dǎo)入數(shù)據(jù)庫(kù) ' ' 為運(yùn)行本程序,應(yīng)在“菜單->工程->部件”中添加“Microsoft Internet Controls” ' 并在“菜單->工程->引用”中添加“Microsoft HTML Object Library” ' Option Explicit Dim Page As Long Private Sub Form_Load() Form1.MousePointer = 11 WebBrowser1.Navigate "www.stockstar.com.cn" ' 起始網(wǎng)址 End Sub Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant) Dim Table1 As HTMLTable, Tables As IHTMLElementCollection Dim Row As HTMLTableRow, Cell As HTMLTableCell Dim i, j, tmp Text2 = WebBrowser1.LocationURL ' 顯示當(dāng)前網(wǎng)址 ' 判斷當(dāng)前網(wǎng)頁(yè)是否全部調(diào)入完畢 If Not (pDisp Is WebBrowser1.Object) Then Exit Sub On Error Resume Next Select Case Text2 Case "http://www.stockstar.com.cn/home.htm" ' 當(dāng)進(jìn)入主頁(yè)面時(shí)執(zhí)行以下程序 ' 用戶注冊(cè)登錄 For i = 0 To WebBrowser1.Document.Forms(0).length - 1 ' 找到 CheckBox 后,將其值改為 False,以防止用戶名及密碼被存儲(chǔ) If WebBrowser1.Document.Forms(0)(i).Name = "checkSavePW" Then _ WebBrowser1.Document.Forms(0)(i).Checked = False If WebBrowser1.Document.Forms(0)(i).Name = "userId" Then _ WebBrowser1.Document.Forms(0)(i).Value = "kompass_china" If WebBrowser1.Document.Forms(0)(i).Name = "passwd" Then _ WebBrowser1.Document.Forms(0)(i).Value = "kompass1" ' 此處是按名字訪問(wèn)按鈕(上例中是按值訪問(wèn)按鈕) If WebBrowser1.Document.Forms(0)(i).Name = "continue" Then _ WebBrowser1.Document.Forms(0)(i).Click Next Case "http://my.stockstar.com/scripts/mystockstar.dll?login" ' 當(dāng)用戶登錄完成后,準(zhǔn)備打開(kāi)表格的第一頁(yè) WebBrowser1.Navigate "http://finance.stockstar.com/scripts/finance.dll?" + _ "showstkdfpm&begin=0&ret=1&index=2&concode=01" Page = 1 Case Else ' 當(dāng)進(jìn)入數(shù)據(jù)頁(yè)面(表格的第一頁(yè)至最后一頁(yè))時(shí)執(zhí)行以下程序 Set Tables = WebBrowser1.Document.getElementsByTagName("Table") For Each Table1 In Tables If Left(Table1.innerText, 2) = "名次" Then ' 找到需要的Table ' 將表格轉(zhuǎn)換成“.csv”格式 For i = 1 To Table1.rows.length - 1 Set Row = Table1.rows(i) j = 0 For Each Cell In Row.cells Text1 = Text1 + Trim(Row.cells(j).innerText) + "," j = j + 1 Next Text1 = Left(Text1, Len(Text1) - 1) + vbCrLf Next ' 數(shù)據(jù)存盤 Open "C:\Data.csv" For Append As #1 Print #1, Left(Text1, Len(Text1) - 2): Text1 = "": Close #1 Exit For End If Next ' 準(zhǔn)備打開(kāi)下一頁(yè) Page = Page + 1 tmp = "http://finance.stockstar.com/scripts/finance.dll?showstkdfpm&ret=" + _ Trim(Str(Page)) + "&index=2&concode=01" If Page <= 54 Then ' 判斷是否瀏覽結(jié)束 WebBrowser1.Navigate tmp Else ' 上網(wǎng)任務(wù)完成后,應(yīng)在此調(diào)用自動(dòng)掛斷過(guò)程。 Form1.MousePointer = 0 MsgBox "Finished!!": End End If End Select End Sub |
以下給出的是上述程序所存數(shù)據(jù)文件的片段:
1,樂(lè)凱膠片,600135,材料,81.493,18.445,23.165,8.850,20.717,10.315 2,歌華有線,600037,傳播娛樂(lè),80.553,13.009,22.256,12.141,20.304,12.844 3,外運(yùn)發(fā)展,600270,倉(cāng)儲(chǔ)運(yùn)輸,80.326,17.331,23.005,8.829,19.900,11.261 4,東方鉭業(yè),0962,有色金屬,80.312,15.160,22.483,11.648,21.290,9.730 5,雙匯發(fā)展,0895,食品,79.772,15.428,20.673,11.508,20.235,11.930 6,四川美豐,0731,化肥,79.361,15.795,23.235,11.323,16.921,12.088 ... ... ... 1059,輪胎橡膠,600623,車類,7.167,8.265,10.973,-34.411,14.120,8.219 1060,PT吉輕工,0546,日用輕工產(chǎn)品,-11.895,5.740,-49.149,7.999,14.136,9.379 1061,廣船國(guó)際,600685,機(jī)械儀器,-57.452,9.824,-1.528,-89.648,14.366,9.533 |
該文章在 2013/11/28 11:35:53 編輯過(guò)
|
|