Board logo

標題: [發問] 如何用EXCEL VBA在CHROME輸入資料再按下查詢? [打印本頁]

作者: smart3135    時間: 2022-7-8 10:59     標題: 如何用EXCEL VBA在CHROME輸入資料再按下查詢?

請教各位大神,我想用VBA抓公司網頁資料,之前都是用IE,語法上大概了解怎麼寫,但現在公司IE停用了,只能用CHROME,我目前只能寫到開啟CHROME網頁,但是如何操作輸入數字按下查詢是完全沒有頭緒,附上開啟CHROME的程式碼以及截圖,懇請各位大神幫忙解惑,萬分感謝。
PS:由於程式碼內的網址是公司內部網頁,所以各位大神在測試的時候沒辦法由外部開啟,還請見諒。
  1. Sub test()
  2. Dim Chrome As New Selenium.ChromeDriver
  3. Dim URL As String
  4. URL = http://etrex2:8080/SelectWeb/
  5. With Chrome
  6.     .Get URL
  7. End With
  8. End Sub
複製代碼
[attach]35021[/attach]
作者: singo1232001    時間: 2022-7-9 16:39

本帖最後由 singo1232001 於 2022-7-9 16:40 編輯

回復 1# smart3135


https://github.com/florentbr/SeleniumBasic/releases
下載
SeleniumBasic-2.0.9.0.exe

更新chrome版本
chrome>說明>關於google chrome

手動第一次更新chromedriver版本
https://chromedriver.chromium.org/
位置C:\Users\xxx\AppData\Local\SeleniumBasic\

安裝並更新後 第一次測試
開始>selenium Basic>Start Chome>跳錯>自動安裝.net fromework>重開機

第二次測試
開始>selenium Basic>Start Chome>click ok to quit




後期引用寫法(避免換電腦還要重設)
set driver = CreateObject("Selenium.ChromeDriver")

操作學習參考網址
https://club.excelhome.net/thread-1452021-1-1.html









自動更新chromedriver  vba代碼(通常一個月左右google會更新瀏覽器一次)
Sub seleniumOPEN()

'利用error方式判斷selenium是否異常 若有異常err就不是0  就會進入 updataSelenium 的程序抓取新的chromedrive版本
Do
    On Error GoTo 0
    On Error Resume Next
    Set driver = CreateObject("Selenium.ChromeDriver")
    Err = 0
    driver.Get "https://www.google.com.tw"   '一定要加https:// 不然會出現神奇的異常現象
    If Err <> 0 Then
            driver.Quit
            Set driver = Nothing
            Call updataSelenium
    End If
Loop Until Err = 0

msgbox "完成"
End Sub


Sub updataSelenium()
'先判斷chromedriver在哪個資料夾
path1 = "C:\Users\" & Environ$("username") & "\AppData\Local\SeleniumBasic\Chromedriver.exe"
path2 = "C:\Program Files\SeleniumBasic\Chromedriver.exe"
If Dir(path1) <> "" Then TempDrvFile = path1
    'Kill (TempDrvFile)  '假如在錯誤的情況下 找到了檔案 那之後將要更新複製覆蓋 避免跳出複製已存在錯誤警告 所以先刪除掉
If Dir(path2) <> "" Then TempDrvFile = path2

'判斷chrome的版本號
Set objHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")  'Get chrome version
chrversion = CreateObject("WScript.Shell").RegRead("HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon\version")
dotsarr = Split(chrversion, ".")
leftchrver = dotsarr(0) & dotsarr(1)

'判斷chromedriver版本號
Set oShell = CreateObject("wscript.shell")
errcode = oShell.Exec(path1 & " --version").StdOut.ReadAll
verarr = Split(errcode, " ")
chrdrv = verarr(1)
dotsarr2 = Split(chrdrv, ".")
leftchrdrv = dotsarr2(0) & dotsarr2(1)
If leftchrver = leftchrdrv Then Exit Sub '利用版本號的前兩位判斷是否同版本


'利用版本號第一位 上官網查詢 當前版本的最終版本號
URL = "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_" & dotsarr(0)
Call objHttp.Open("GET", URL, False)
Call objHttp.Send("")
version_number = objHttp.responseText
dotsarr3 = Split(version_number, ".")
leftversion_no = dotsarr3(0) & dotsarr3(1)
download_url = "https://chromedriver.storage.googleapis.com/" + version_number + "/chromedriver_win32.zip"
   
    '利用取得的版本號 取得下載網址 並開啟chromedriver.zip下載頁面
    Call objHttp.Open("GET", download_url, False)
    Call objHttp.Send("")
        
        '開啟adodb接收下載壓縮檔 並放入selenium的資料夾
        Set fileStream = CreateObject("ADODB.Stream")
        With fileStream
            .Open
            .Type = 1 'adTypeBinary
            .Write objHttp.responseBody
            .Position = 0
            .SaveToFile "C:\Users\" & Environ$("username") & "\AppData\Local\SeleniumBasic\chromedriver.zip", 2  'adSaveCreateOverWrite 'adSaveCreateOverWrite
            .Close
        End With
        
        '解壓縮 會先將舊版的刪除 才解壓縮
        Set oApp = CreateObject("Shell.Application")
        If Dir(path1) <> "" Then Kill path1
        oApp.Namespace("C:\Users\" & Environ$("username") & "\AppData\Local\SeleniumBasic\").CopyHere _
            oApp.Namespace("C:\Users\" & Environ$("username") & "\AppData\Local\SeleniumBasic\chromedriver.zip").Items


'全部完成後 會回到上一個sub 並重新判斷是否版本錯誤
End Sub
作者: singo1232001    時間: 2022-7-9 18:05

本帖最後由 singo1232001 於 2022-7-9 18:09 編輯

回復 1# smart3135


需要附上 那兩個元件的相關資訊  例如ID  class  tagname   
     
要在瀏覽器按F12  並在想查的元件上面         右鍵  >檢查 (重複2次)

尤其是某些內部網頁藏框架 就算上述 你有給

也可能因為iframe不同框架 無法用  但可以先試試

另外補充 有ID簡單一點
沒ID 就要順著 祖孫階層 展開全抓
作者: smart3135    時間: 2022-7-10 00:00

回復  smart3135


https://github.com/florentbr/SeleniumBasic/releases
下載
SeleniumBasic-2.0.9 ...
singo1232001 發表於 2022-7-9 16:39


感謝您提供的這些資訊,會再好好消化一下。
作者: smart3135    時間: 2022-7-10 00:21

本帖最後由 smart3135 於 2022-7-10 00:32 編輯
回復  smart3135


需要附上 那兩個元件的相關資訊  例如ID  class  tagname   
     
要在瀏覽器按F ...
singo1232001 發表於 2022-7-9 18:05

您好,原來我一開始就搞錯了,不是在網頁按右鍵選檢查網頁原始碼,而是要按F12查元件,後來有詢問到,應該是要用.FindElementById、.FindElementByName、.FindElementByXPath的語法,如下面用Yahoo奇摩首頁搜尋的例子
  1. Sub test()
  2.     Dim chrome As New Selenium.ChromeDriver, UrL As String, s  As String
  3.     UrL = "https://tw.yahoo.com/"
  4.     s = "尿布"
  5.         With chrome
  6.         .Get UrL
  7.         .FindElementById("header-search-input").SendKeys (s)
  8.         .FindElementById("header-desktop-search-button").Click
  9.        End With
  10.      Stop
  11.      chrome.Quit
  12.     Set chrome = Nothing
  13.     End Sub
複製代碼
以奇摩這個case來說,元件是用ID,所以是用.FindElementById,下週到公司會再用F12查詢一次元件的相關資訊再附上圖片,在此之前有幾個疑問想先請教您
1.在奇摩首頁,我按下F12,一開始並沒辦法找到"header-search-input"和"header-desktop-search-button"這兩個關鍵詞,是等按下Crl+F搜尋框出現後key入search後才出現,不太理解為什麼要在這樣操作後才會出現關鍵詞,我這樣的作法是正確的嗎?或是有其他比較正確的方法可以查到"header-search-input"和"header-desktop-search-button"這兩個關鍵詞?
[attach]35027[/attach]
2.您說在想查的元件上面         右鍵  >檢查 (重複2次),這裡不是很懂,可以再詳述一下或是提供參考圖片嗎?
先感謝您的指導
作者: singo1232001    時間: 2022-7-10 01:30

回復 5# smart3135


    在元件上 檢查兩次 才會全展開

    第一次只會選擇到元件的上層或者框架
    第二次才會自動跳到元件本身
作者: smart3135    時間: 2022-7-10 23:14

回復  smart3135


    在元件上 檢查兩次 才會全展開

    第一次只會選擇到元件的上層或者框架
   ...
singo1232001 發表於 2022-7-10 01:30

可以再和您確認一下嗎?是左鍵兩次還是右鍵兩次?我按右鍵會出現圖中紅框的視窗。
[attach]35028[/attach]
作者: singo1232001    時間: 2022-7-11 03:43

本帖最後由 singo1232001 於 2022-7-11 03:58 編輯

回復 7# smart3135


其實可以不用按F12

(右鍵>檢查)做兩次    不是右邊的紅框,而是左邊的顯示畫面上直接操作

中文版的是"檢查"  英文版的我忘了




若畫面有封鎖  就要先F12 然後右邊的程式碼  用滑鼠上下移動  看左邊畫面哪裡被框起來 就能逐漸找到

或者安裝google chrome商店的 Selenium IDE 擴充功能 來抓(遇到藏很深的才需要)

比如你說的那個搜尋欄就是
chrome.FindElementById("header-search-input").clear
chrome.FindElementById("header-search-input").sendkey "關鍵字"
點擊查詢按鈕
chrome.FindElementById("header-desktop-search-button").click





1.另外建議 在編寫過程 千萬不要用with 的寫法 這會造成你測試麻煩
2.ID通常只有1個 所以很好少
3.非ID的元件 通常不只1個  就可以+s
例如:
set tag1 = chrome.FindElementByTag("input")   這頁面至少超過10個以上
就該改成
set tag1 = chrome.FindElementsByTag("input")

這樣就能在之後把所有的input 都放入 tag1 內 並像陣列物件一樣 會自動編號

之後就可以單獨選擇
tag1(0)
tag1(1)
.
.
.
.
.
tag1(tag1.count) 內的東西了





補充
要不要set 就看你之後還要不要繼續用
如上述例子
chrome.FindElementById("header-search-input").clear
chrome.FindElementById("header-search-input").sendkey "關鍵字"
當下sendkey 或者click 就沒必要額外set
當然 也可以
set id1 = chrome.FindElementById("header-search-input")
id1.clear
id1.sendkey "關鍵字"
作者: quickfixer    時間: 2022-7-11 05:44

本帖最後由 quickfixer 於 2022-7-11 05:51 編輯

回復 8# singo1232001


    1.另外建議 在編寫過程 千萬不要用with 的寫法 這會造成你測試麻煩

看樓主的程式碼,用with結構漂亮,也只用了1個,不會有問題
我google到用with只有好處
我不像你這麼精通程式,搞不清楚這幾行程式碼會出什麼問題
請教一下這種with寫法會出現什麼麻煩?


https://docs.microsoft.com/zh-tw/dotnet/visual-basic/language-reference/statements/with-end-with-statement
如果您的程式碼會在多個陳述式中存取相同物件,使用 With 陳述式有下列好處:

您不需要多次評估複雜的運算式或指派結果給暫存變數,以多次參考其成員。

您可以讓程式碼更容易讀取,方法是排除重複的限定運算式。
作者: smart3135    時間: 2022-7-12 11:12

回復  smart3135


其實可以不用按F12

(右鍵>檢查)做兩次    不是右邊的紅框,而是左邊的顯示畫面 ...
singo1232001 發表於 2022-7-11 03:43

您好,今天到公司用了滑鼠右鍵選檢查,真的能找到對應的元件內容,只是還是不是很清楚這個FindElement該怎麼寫,可否再麻煩您幫忙看一下,若還需要其他資訊請再告知,非常感謝您。

1.首先現在Search點一下
[attach]35031[/attach]


2.在請輸入工單號碼欄位輸入工單號碼
[attach]35032[/attach]

3.按下查詢即可得到結果
[attach]35033[/attach]
作者: singo1232001    時間: 2022-7-12 16:15

本帖最後由 singo1232001 於 2022-7-12 16:29 編輯

回復 10# smart3135



1.你這個有frame
https://club.excelhome.net/thread-1452021-3-1.html
參考30樓 再不行 直接google 用純英文 找看看有沒有範例


2.沒辦法 只能多次利用 set tag1 = chrome.findelementsbytag("xxx")(0)   一層一層慢慢往下邊測邊找
xxx 就是最前面<> 中的紫色文字  例如 center form table tbody tr td input
(0) 看物件組內的第幾個是你要的 可以用迴圈 或者.text 或.value 來debug.print 確認是不是你要的該元件

邊找也可以額外 利用   迴圈 + instr + .attribute  的方式模糊搜索




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)