iamlaosong文
一個項目需要全國重點城市間的距離,網上有這種查詢,可是手工查詢的速度是無法忍受的,所以需要通過程式自動抓取。這兒說一下其中的關鍵點。
查詢的網址是http://tools.2345.com/jiaotong/lc.htm,這兒截取該網頁的部分原始碼,以便分析:
<h2><img src="../img/jiaotong/icon_gllcs.png" />公路裡程查詢</h2><div class="description">為您提供全國公路裡程查詢,快速計算出兩地間的裡程數。</div><div class="traffic_main clearfix"> <div class="mod_1b code_search_gl clearfix"> <div class="gl_txt_form"> <input id="start" autocomplete="off" type="text" value="出發地" class="txt" onfocus="this.className='txt txt_focus';if (this.value == '出發地')this.value='';" onblur="this.className='txt';if (this.value == '')this.value='出發地';" /> <a class="pos_c"></a> </div> <a href="javascript:void(0);" class="ec_gl"></a> <div class="gl_txt_form"> <input id="end" autocomplete="off" type="text" value="目的地" class="txt" onfocus="this.className='txt txt_focus';if (this.value == '目的地')this.value='';" onblur="this.className='txt';if (this.value == '')this.value='目的地';" /> <a class="pos_c"></a> </div><input type="button" class="btn" value="查詢" onclick="doSearch()" onmouseover="this.className='btn btn_hover'" onmouseout="this.className='btn'" /><div id="load" style="width:406px; text-align:center; padding-top:10px; display:none;"><img src="/img/life/load.gif" /></div> <!--查詢結果--><div class="gl_result" id="gl_result" style="display:none"> 公路裡程: <span id="res"></span> 公裡 <a id="lnk" href="#" target="_blank">(查看自駕線路)</a> </div> <!--查詢結果 end--></div>
定位網頁中元素的最有效函數是GetElementById,因為網頁中的id都是唯一的。通過上面的HTML代碼可以發現,“出發地”和“目的地”都可以通過id來定位,在VB中可以用下面陳述式完成這兩個內容的輸入:
WebBrowser1.Document.GetElementById("start").innertext = StartCity
WebBrowser1.Document.GetElementById("end").innertext = EndCity
其中StartCity和EndCity是兩個變數,內容為城市名稱。可是查詢提交按鈕中卻沒有id屬性,所以要定位這個按鈕,就要先定位這個元素,用函數getElementsByTagName可以獲得某元素名稱的所有元素的數組,再用下標序號進行引用。通過下面的調試代碼可以確定查詢按鈕的序號:
For i = 0 To WebBrowser1.Document.getElementsByTagName("input").Length - 1
Debug.Print i & " " & WebBrowser1.Document.getElementsByTagName("input")(i).Value
Next i
調試這段代碼,在“立即視窗”顯示的內容如下:
0 周公解夢
1 5823820519378234798
2 gbk
3 搜工具
4 合肥
5 南京
6 查詢
由此可知,查詢按鈕的序號是6,於是通過下面語句可以實現查詢提交:
WebBrowser1.Document.getElementsByTagName("input")(6).Click
這兒說明一下,上面顯示的input元素的value值前面幾個(0-3)在瀏覽器中的查看原始碼是看不到的,估計這幾個輸入應該是js程式執行後產生的,想要看到網頁產生後真實的原始碼,可以用下面語句實現:
Debug.Print WebBrowser1.Document.body.innerhtml
逐步執行這句代碼後,“立即視窗”就可以看到完整的網頁原始碼了。
最後,用下面這段代碼實現距離的抓取:
tim1 = Timer
Do
Loop While Timer < tim1 + 1 '稍等片刻
Do
Str = WebBrowser1.Document.GetElementById("res").innertext
i1 = Len(Str)
DoEvents
If Timer > tim1 + 20 Then Exit Do '逾時退出
Loop While i1 = 0
CityDistance = Str '距離到手
下面是這個抓取函數的完整代碼:
'從http://tools.2345.com/jiaotong/lc.htm網址抓城市間距離Public Function CityDistance(StartCity As String, EndCity As String) As String Dim Str As String Dim i1 As Integer On Error GoTo cityErr WebBrowser1.Navigate "http://tools.2345.com/jiaotong/lc.htm" tim1 = Timer Do Loop While Timer < tim1 + 1 '稍等片刻 Do Until WebBrowser1.ReadyState = 4 DoEvents Loop WebBrowser1.Document.GetElementById("start").innertext = StartCity WebBrowser1.Document.GetElementById("end").innertext = EndCity WebBrowser1.Document.getElementsByTagName("input")(6).Click 'For i = 0 To WebBrowser1.Document.getElementsByTagName("input").Length - 1 ' Debug.Print i & " " & WebBrowser1.Document.getElementsByTagName("input")(i).Value 'Next i tim1 = Timer Do Loop While Timer < tim1 + 1 '稍等片刻 Do Str = WebBrowser1.Document.GetElementById("res").innertext i1 = Len(Str) DoEvents If Timer > tim1 + 20 Then Exit Do '逾時退出 Loop While i1 = 0 CityDistance = Str '距離到手 Exit Function cityErr: 'Debug.Print Err.Number & Err.Description Err.Clear Resume End Function