之前曾經用Python爬蟲Google搜尋結果
Py / 透過谷狗大神爬學校地址
最近因為要處理各縣市回傳的報名表
也會需要處理學校名單的地址
這次想試試看用VBA的方式來爬學校地址
備註:剛開始是想用Google Apps Script的UrlFetchApp.fetch
但是測試很久都沒辦法完整抓到網頁資料,之後再看看有沒有其他的方式
透過VBA有兩種方式可以取得網頁資料
第1種是模擬操作網頁瀏覽器
第2種是使用XMLHTTP物件
1.網頁瀏覽器
這個方式跟在Python使用selenium-webdrive一樣
而在VBA如果要使用selenium-webdrive
要安裝SeleniumBasic
然後再下載最新的chromedriver或edgedriver
取代原本SeleniumBasic安裝時的舊版本檔案
要注意的是從Microsoft Edge Driver下載回來的檔案,檔案名稱不是edgedriver
所以要記得手動改名
前置作業完成之後,在VBA引用Selenium Type Library即可
以下是簡易的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Public BOT As New WebDriver Sub WebDriver() s = Application.EncodeURL("壯圍國中") BOT.Start "edge" BOT.Get "https://www.google.com/search?q=" + s s = BOT.FindElementsByClass("LrzXr")(1).Text Debug.Print s Application.Wait (Now + TimeValue("00:00:03")) BOT.Quit End Sub |
透過 WebDriver取得的網頁內容,可以利用FindElementsByClass等方式,利用DOM取得目標資料
由於是爬蟲程式,要避免短時間大量發出網頁要求,所以用 Application.Wait 設定暫停時間
之後想再改成亂數取1~5秒
2.XMLHTTP物件
在這邊要先補充VBA引用物件的方式分為2種
Early Binding 和 Late Binding
Early Binding 就是先在工具->設定引用項目->勾選
之後用 New 物件名稱來建立物件
Late Binding 則是透過CreateObject(物件名稱)
所以1.透過網頁瀏覽器是用Early Binding
下面的程式碼則是 Late Binding
由於透過xmlHttp取得的responseText就只是文字檔
VBA本身也無法解析Html
所以就只能單純分割字串
要再補充的一點
透過這個方式取得的網頁內容是不同於selenium-webdrive取得的網頁內容
selenium-webdrive想要取得的資料是在Class名稱為LrzXr的span裡
而xmlHttp則是在Class名稱為BNeawe tAd8D AP7Wnd的span裡
而且整個網頁內容不只有一個使用BNeawe tAd8D AP7Wnd的標籤
因此在分析網頁內容之後,透過最接近的關鍵字”地址”
作為第一個分割點,然後再以此為起點來取得BNeawe tAd8D AP7Wnd的位置
之後取得在這之後的第一個</span>做為結束點
後續的程式碼也是一樣要加入間隔時間
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
Public Sub xmlHttpGoogle() s = Application.EncodeURL("壯圍國中") '使用Microsoft.XMLHTTP物件,傳送網址給對方,然後取回(GET)回傳資料 Set WinHttpReq = CreateObject("MSXML2.serverXMLHTTP") 'WinHttpReq.Open "GET", myURL, False, "username", "password" WinHttpReq.Open "GET", "https://www.google.com/search?q=" + s, False WinHttpReq.send '將回傳資料放到strBody變數 strBody = WinHttpReq.responseText '確認回傳的狀態是否正常,200代表正常 If WinHttpReq.Status = 200 Then ' Debug.Print strBody End If '分割字串 '起始位置 iDocumentId_Start = InStr(1, strBody, "地址") iDocumentId_Start = InStr(iDocumentId_Start, strBody, "<span class=" + Chr(34) + "BNeawe tAd8D AP7Wnd" + Chr(34) + ">") + Len("<span class=" + Chr(34) + "BNeawe tAd8D AP7Wnd" + Chr(34) + ">") '結束位置 iDocumentId_End = InStr(iDocumentId_Start, strBody, "</span>") '取出字串 ss = Mid(strBody, iDocumentId_Start, iDocumentId_End - iDocumentId_Start) Debug.Print iDocumentId_Start Debug.Print iDocumentId_End Debug.Print ss End Sub |
參考資料
[vba][vba selenium]vba selenium的安裝與使用