天天看點

WebBrowser控件網頁資料抓取(I) - EXCEL VBA(22)

作者:銀河統計工作室

運用WebBrowser控件打開Web頁面,并提取頁面資料成為當今資料收集的主要手段。EXCEL VBA網頁資料抓取和處理基本過程如下:

  • 運用WebBrowser控件打開Web頁面
  • 解析文檔或字元串
  • 将抓取的網頁資料按格式要求寫入EXCEL表格
  • 通過EXCEL表格函數或EXCEL VBA程式設計進行資料數理

本文介紹開發一個簡單的WebBrowser控件網頁資料抓取工具來實作EXCEL VBA網頁資料抓取的基本過程。

1、運用WebBrowser控件打開Web頁面

I、建立窗體如下圖

WebBrowser控件網頁資料抓取(I) - EXCEL VBA(22)

窗體由控件解釋:

  • CommandButton1:【打開網頁】指令按鈕;
  • CommandButton2:【網頁資料抓取】指令按鈕;
  • TextBox1:網址文本框(單行)
  • TextBox2:網頁HTML文檔文本框(多行)。設定Multiline屬性為True、ScrollBars屬性為2;
  • WebBrowser1:網頁控件

II、打開Web頁面

  • 打開窗體後運用窗體初始化事件Initialize加載指定網頁
Private Sub UserForm_Initialize()
WebBrowser1.Navigate "http://www.galaxystatistics.com/excel/excelVBA2.html"
End Sub           
  • 打開窗體時運用CommandButton1【打開網頁】指令按鈕打開TextBox1網址文本框中指定的網頁
Private Sub CommandButton1_Click()
WebBrowser1.Navigate TextBox1.Text
End Sub           
  • 網頁加載成功後執行WebBrowser1的DocumentComplete事件,在TextBox2文本框顯示網頁HTML文檔
Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
Dim doc As Object
Set doc = WebBrowser1.Document
TextBox2.Text = doc.DocumentElement.innerHTML
TextBox2.SetFocus
End Sub           

通常,使用浏覽器打開網頁後,在頁面點選滑鼠右鍵,彈出菜單如此,

WebBrowser控件網頁資料抓取(I) - EXCEL VBA(22)

點選【檢視網頁源代碼(V)】,可以檢視網頁HTML文檔。

本文案例網頁為“http://www.galaxystatistics.com/excel/excelVBA2.html”,文檔如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Excel Train</title>
<meta charset="utf-8"/>
<style>
.testTB{color:#ff0000;}
</style>

<script type="text/javascript">
function oSum(x,y) {
return x+y;
}
//無參數調用  
function alertNull(){  
alert("WebBrowser call!");  
}
//有參數調用  
function callWithPar(name, address) {  
alert("Name is " + name + "; address is " + address);  
}  
 </script>
</head>
<body scroll="yes" bgcolor="#E3F3F9" style="border:none">
<h4>表格一</h4>
<table id="myTB2" class="testTB" border=0 cellspacing=0 cellpadding=5 width="100%" style="border-top:2px solid #000000; border-bottom:2px solid #000000; width:50%;">
      <tr><th style="border-right:1px solid #000000;">産量</th><th style="border-right:1px solid #000000;">人數</th><th>累計人數</th></tr>
      <tr>
          <td style="border-top:1px solid #000000; border-right:1px solid #000000;">4</td>
          <td style="border-top:1px solid #000000; border-right:1px solid #000000;">8</td>
          <td style="border-top:1px solid #000000;">8</td>
      </tr>
      <tr>
          <td style="border-right:1px solid #000000;">5</td>
          <td style="border-right:1px solid #000000;">22</td>
          <td>30</td>
      </tr>
      <tr>
          <td style="border-right:1px solid #000000;">6</td>
          <td style="border-right:1px solid #000000;">42</td>
          <td>72</td>
      </tr>
      <tr>
          <td style="border-right:1px solid #000000;">7</td>
          <td style="border-right:1px solid #000000;">38</td>
          <td>110</td>
      </tr>
      <tr>
          <td style="border-right:1px solid #000000;">8</td>
          <td style="border-right:1px solid #000000;">17</td>
          <td>127</td></tr>
      <tr>
          <td style="border-right:1px solid #000000;">9</td>
          <td style="border-right:1px solid #000000;">3</td>
          <td>130</td>
      </tr>
      <tr>
          <td style="border-top:1px solid #000000; border-right:1px solid #000000;">合計</td>
          <td style="border-top:1px solid #000000; border-right:1px solid #000000;">130</td>
          <td style="border-top:1px solid #000000;">***</td>
      </tr>
  </table>
<p>
<h4>表格二</h4>
<table class="testTB" border=1 cellspacing=0 cellpadding=5 width="50%">
<tr><th>姓名</th><th>民族</th></tr>
<tr><td>張三</td><td>漢族</td></tr>
<tr><td>李四</td><td>回族</td></tr>
</table>
<form name="myFc">
<h4>表格三</h4>
<table>
<tr><th colspan=2 style="text-align:left; font-size:10pt; color:#a51020;">1、文本框</th></tr>
<tr><td>  姓名:</td><td><input id="myName" style="width:100px; color:#ff0000;" value="張三" onchange="alert(111)"/></td></tr>
<tr><th colspan=2 style="text-align:left; font-size:10pt; color:#e51020;">2、單選按鈕</th></tr>
<tr><td>  性别:</td><td><input type="radio" name="myGender" value="1" checked/>男 <input type="radio" name="myGender" value="0"/>女</td></tr>
<tr><th colspan=2 style="text-align:left; font-size:10pt; color:#e51020;">3、複選框</th></tr>
<tr><td>  愛好:</td><td><input type="checkbox" name="myLike" value="1"/>籃球 <input type="checkbox" name="myLike" value="2"/>遊泳 <input type="checkbox" name="myLike" 
value="3"/>跑步</td></tr>
<tr><th colspan=2 style="text-align:left; font-size:10pt; color:#e51020;">4、下拉清單</th></tr>
<tr><td>  專業:</td><td><select id="myMajor">
    <option value="1">數學</option>
    <option value="2">統計學</option>
    <option value="3">壽險精算</option>
    <option value="4">R語言</option>
</select></td></tr>
<tr><th colspan=2 style="text-align:left; font-size:10pt; color:#e51020;">5、多行文本</th></tr>
<tr><td>  簡介:</td><td>
<textarea id="myIntroduction" style="width:300px; height:100px; color:#555555;">
WebBrowser控件是Internet Explorer的主視窗,它是作為一個ActiveX控件來包裝的。使用者可以使用WebBrowser控件打開任何IE能夠顯示的Web頁面,并提取頁面資料。如有自己的網站,可運用WebBrowser控件實作
EXCEL文檔和伺服器間資料交換
</textarea></td></tr>
<tr><th colspan=2 style="text-align:left; font-size:10pt; color:#e51020;">6、DIV區塊</th></tr>
<tr><td>  效果:</td><td>
<div id="myEffect" style="width:300px; height:50px; border:#aaaaaa 1px solid; dsiplay:inline;">
<b style="text-align:center; width:100%; padding-top:15px;">這是黑體效果</b>
</div></td></tr>
<tr><th colspan=2 style="text-align:left; font-size:10pt; color:#e51020;">7、圖檔</th></tr>
<tr><td>  頭像:</td><td><img src="http://studio.galaxystatistics.com/shiny/rSHIndex/pic/vba1.jpg" id="myImg" style="width:200px; height:260px; color:#ff0000;"/></td></tr>
<tr><th colspan=2 style="text-align:left; font-size:10pt; color:#e51020;">8、内崁iFrame架構</th></tr>
<tr><td>  架構:</td><td><iframe src="http://www.galaxystatistics.com/excel/excelVBA1.html" id="myIframe" style="width:380px; height:260px; color:#ff0000;"/></td></tr>
</table>
</form>
</body>
</html>           

2、解析HTML文檔

WebBrowser控件網頁資料抓取必須具備一定基礎的網頁程式設計知識。通常,網頁資料抓取的對象為網頁中的table标簽,統計資料往往以表格形式來呈現。

I、通過table标簽的id屬性抓取表格資料

網頁中任何标簽都可以設定id屬性做為唯一辨別,對于設定id屬性的HTML标簽,可以用DOM文檔模型的Document.getElementById獲得該标簽。

案例網頁為“http://www.galaxystatistics.com/excel/excelVBA2.html”中第一個table标簽為,

<h4>表格一</h4>
<table id="myTB2" class="testTB" border=0 cellspacing=0 cellpadding=5 width="100%">
 ...
  </table>           

這裡table标簽的id屬性為id="myTB2",CommandButton2【網頁資料抓取】指令按鈕代碼如下:

Private Sub CommandButton2_Click()
Dim tbRows As Integer
Dim tbCols As Integer
Dim i, j As Integer
'通過id屬性獲得table标簽對象
Set doc = WebBrowser1.Document.getElementById("myTB2")
'獲得表格行數
tbRows = doc.Rows.Length
'獲得表格列數
tbCols = doc.Rows(0).Cells.Length
Sheet1.Cells.Clear
For i = 0 To tbRows - 1
    For j = 0 To tbCols - 1
'按行、列将表格資料寫入EXCEL表格
        Sheet1.Cells(i + 1, j + 1) = doc.Rows(i).Cells(j).innerText
   Next j
Next i
End Sub           

II、通過table标簽集合抓取表格資料

有時網頁中要抓取的标簽沒設定id屬性,這時可通過DOM文檔模型的Document.getElementsByTagName獲得該标簽集合。CommandButton2【網頁資料抓取】指令按鈕代碼如下:

Dim tables As Object
' 擷取文檔中所有的table集合
Set tables = WebBrowser1.Document.getElementsByTagName("table")
' 擷取文檔中第2個table對象
Set doc = tables(1)
Dim tbRows As Integer
Dim tbCols As Integer
Dim i, j As Integer
tbRows = doc.Rows.Length
tbCols = doc.Rows(0).Cells.Length
Sheet1.Cells.Clear
For i = 0 To tbRows - 1
  For j = 0 To tbCols - 1
    Sheet1.Cells(i + 1, j + 1) = doc.Rows(i).Cells(j).innerText
  Next j
Next i           

解析HTML文檔是一個人機對話過程,開發者需要對HTML文檔結構和EXCEL VBA程式設計有足夠的經驗。

這裡介紹了網頁table标簽中資料抓取的方法,對于其它網頁标簽(div、textarea、img等),基本都可以有DOM的Document.getElementById和Document.getElementsByTagName方法獲得抓取對象。至于不同網頁标簽的進一步解析,則需要對HTML文檔結構有一定程度的了解。

本文代碼使用InternetExplorer運作通過,如果使用Chrome浏覽器或Firefox浏覽器加載網頁,HTML文檔解析過程可能略有差別。

參考文章:

  • Web Browser控件與網頁互動 - EXCEL VBA(21)

繼續閱讀