Board logo

標題: [分享] 轉換ie物件語法為Selenium(chrome) ? [打印本頁]

作者: t8899    時間: 2022-9-23 06:38     標題: 轉換ie物件語法為Selenium(chrome) ?

Sub IE345678()
    Set Ie = CreateObject("InternetExplorer.Application")
    Ie.Navigate "https://mis.twse.com.tw/stock/group.jsp?type=fixed&ex=tse&ind=TIDX#STATISTICS"
Do While Ie.Busy Or Ie.ReadyState <> 4: DoEvents: Loop
    Dim I As Integer, S As Integer, k As Integer, J As Integer
     Dim Element
    Set Element = Ie.document.getelementsbytagname("table")
    With Sheets("sheet1")
      .Range("a1:f17").ClearContents
        For S = 4 To 5               
            For I = 0 To Element(S).Rows.Length - 1
                k = k + 1
                For J = 0 To Element(S).Rows(I).Cells.Length - 1  
               .Cells(k, J + 1) = Element(S).Rows(I).Cells(J).innerText
                Next
            Next
        Next
    End With
    Set Element = Nothing
end sub

請教此ie物件如何轉換成Selenium(chrome)的語法?
作者: singo1232001    時間: 2022-9-23 18:32

回復 1# t8899


Sub test()
Set driver = CreateObject("Selenium.ChromeDriver")
driver.get "https://mis.twse.com.tw/stock/group.jsp?type=fixed&ex=tse&ind=TIDX#STATISTICS"  '如果卡在這裡 瀏覽器沒開成 要注意chromedriver版本是否更新
Set tb = driver.findelementsbytag("table")
Cells.ClearContents
For Each Z In tb
r = Cells(Rows.Count, 1).End(3).Row + 3
Z.astable.toexcel Cells(r, 1)
Next
End Sub
作者: t8899    時間: 2022-9-23 20:15

本帖最後由 t8899 於 2022-9-23 20:17 編輯

回復 2# singo1232001
謝謝指導,最後面需不需要 tb.quit ?? (像ie.quit)
如果只要table 3 , 語法是?
作者: t8899    時間: 2022-9-23 20:56

本帖最後由 t8899 於 2022-9-23 21:01 編輯

回復 2# singo1232001
上面的問題已找到答案

1.我如果只要 tb("6") 的第三欄第三列這個儲存的值(圖中黃色)的語法是?
2.執行時 隱藏chrome視窗的語法 ??
[attach]35235[/attach]
作者: quickfixer    時間: 2022-9-23 23:53

回復 4# t8899


    Set tb = driver.FindElementsByTag("table")(6)
MsgBox tb.FindElementsByTag("tr")(3).FindElementsByTag("td")(3).Text
作者: t8899    時間: 2022-9-24 05:58

回復  t8899


    Set tb = driver.FindElementsByTag("table")(6)
MsgBox tb.FindElementsByTag("tr ...
quickfixer 發表於 2022-9-23 23:53

謝謝指導
1 執行時 隱藏chrome視窗的語法 ??
2.只抓表格6的第二欄語法?
作者: singo1232001    時間: 2022-9-24 08:45

本帖最後由 singo1232001 於 2022-9-24 08:54 編輯

回復 6# t8899


    Sub test2()
Cells.ClearContents

Set driver = CreateObject("Selenium.ChromeDriver")
'driver.AddArgument ("headless") '無頭視窗
  'driver.Wait 1500 '沒有加等待1.5秒 會少一次網頁完成停頓 資料來不及近來 秒數依照電腦效能網路速度調整
    driver.get "https://mis.twse.com.tw/stock/group.jsp?type=fixed&ex=tse&ind=TIDX#STATISTICS"

Set tbl6 = driver.findelementsbytag("table")(6)    '<table> 第六個table
                  r = Cells(Rows.Count, 1).End(3).Row + 1
                     Cells(r, 1) = tbl6.findelementsbytag("th")(2).Text '<th> "整體市場的標題"

  Set tby1 = tbl6.findelementsbytag("tbody")(1)      '<tbody> 第一個tbody
    Set tr = tby1.findelementsbytag("tr")          '找到全部tr後  每個tr的第二個td

       For Each Z In tr
           r = Cells(Rows.Count, 1).End(3).Row + 1
          Cells(r, 1) = Z.findelementsbytag("td")(2).Text   'td第二
       Next
End Sub

擔心原po看不懂順序 (可以對照著網頁的標籤看)
另外不只這種標籤式的查找
也有其他種類的方法
只是這種比較不容易讓新手在網頁中迷路
當你練得很純熟的時候,可以像5樓q大那樣連著寫比較快
作者: singo1232001    時間: 2022-9-24 13:34

本帖最後由 singo1232001 於 2022-9-24 13:37 編輯

Sub 分解步驟版()
Cells.ClearContents
Set driver = CreateObject("Selenium.ChromeDriver")
    driver.AddArgument ("headless") '無頭視窗
    driver.Wait 1500
    driver.get "https://mis.twse.com.tw/stock/group.jsp?type=fixed&ex=tse&ind=TIDX#STATISTICS"

Set tbl6 = driver.findelementsbytag("table")(6)
  Set tby1 = tbl6.findelementsbytag("tbody")(1)
    Set tr2 = tby1.findelementsbytag("tr")(2)
      Set td2 = tr2.findelementsbytag("td")(3)
        Cells(1, 1) = td2.Text
End Sub


Sub 一氣呵成版()
Cells.ClearContents
Set driver = CreateObject("Selenium.ChromeDriver")
    driver.AddArgument ("headless") '無頭視窗
    driver.Wait 1500
    driver.get "https://mis.twse.com.tw/stock/group.jsp?type=fixed&ex=tse&ind=TIDX#STATISTICS"

Cells(1, 1) = driver.findelementsbytag("table")(6). _
               findelementsbytag("tbody")(1). _
               findelementsbytag("tr")(2). _
               findelementsbytag("td")(3). _
               Text
End Sub

'兩種寫法都一樣







'如果要加上完全自動更新
Sub Chrome更新時自動更新_and_分解步驟版()

Do
    On Error GoTo 0
    On Error Resume Next
    Set driver = CreateObject("Selenium.ChromeDriver")
        driver.AddArgument ("headless")
    Err = 0
    driver.Start
    If Err <> 0 Then
      If Exit5 > 5 Then Exit Sub  '若執行超過5次就不跑了
      driver.Quit
      Set driver = Nothing
      Exit5 = Exit5 + 1
      Call updataSelenium
    End If
Loop Until Err = 0
Set driver = Nothing




Cells.ClearContents
Set driver = CreateObject("Selenium.ChromeDriver")
    driver.AddArgument ("headless") '無頭視窗
    driver.Wait 1500
    driver.get "https://mis.twse.com.tw/stock/group.jsp?type=fixed&ex=tse&ind=TIDX#STATISTICS"

Cells(1, 1) = driver.findelementsbytag("table")(6). _
               findelementsbytag("tbody")(1). _
               findelementsbytag("tr")(2). _
               findelementsbytag("td")(3). _
               Text
End Sub

Sub updataSelenium()  '如果中途就跳離 可能是檔案位置要重新確認 或者 舊版本檔案沒刪除導致程序無法執行 也可能是壓縮檔解壓過程出問題 也可能是下載檔案出問題 主要F8逐步看哪段跳離
'找到chromedriver的檔案位置 有的電腦位置不同 通常是這兩個位置其一
'確認chromedriver正確的檔案路徑 與正確的資料夾路徑
path1 = "C:\Users\" & Environ$("username") & "\AppData\Local\SeleniumBasic\Chromedriver.exe"
path2 = "C:\Program Files\SeleniumBasic\chromedriver.exe"
If Dir(path1) <> "" Then TempDrvFile = path1
If Dir(path2) <> "" Then TempDrvFile = path2
foler = Left(TempDrvFile, InStrRev(TempDrvFile, "\"))

'查找電腦當前的google版本號
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(TempDrvFile & " --version").StdOut.ReadAll
verarr = Split(errcode, " ")
chrdrv = verarr(1)
dotsarr2 = Split(chrdrv, ".")
leftchrdrv = dotsarr2(0) & dotsarr2(1)
If leftchrver = leftchrdrv Then Exit Sub

'若不符 ,則上官網查最新chromeDriver版本號
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版本號 找到下載路徑
    Call objHttp.Open("GET", download_url, False)
    Call objHttp.Send("")
        
        '下載檔案,並更正成壓縮檔副檔名
        Set fileStream = CreateObject("ADODB.Stream")
        With fileStream
            .Open
            .Type = 1 'adTypeBinary
            .Write objHttp.responseBody
            .Position = 0
            .SaveToFile foler & "chromedriver.zip", 2
            .Close
        End With
        
        '解壓縮(解壓前程序會先刪掉舊的)
        On Error GoTo 0
        Set oApp = CreateObject("Shell.Application")
        If Dir(TempDrvFile) <> "" Then Kill TempDrvFile
        oApp.Namespace(foler).CopyHere _
            oApp.Namespace(foler & "chromedriver.zip").items
End Sub
作者: t8899    時間: 2022-9-24 14:01

本帖最後由 t8899 於 2022-9-24 14:03 編輯

回復 8# singo1232001
謝謝您熱心指導
我看程序執行完CHROME 會自動關閉(退出),不用再多  DRIVER.Quit ??
作者: singo1232001    時間: 2022-9-24 14:39

本帖最後由 singo1232001 於 2022-9-24 14:51 編輯

回復 9# t8899



若你不想關閉 可以這樣寫

Dim driver '<--這要置頂 最頂部 在這之上不能有任何字
Sub 不關閉分解步驟版()
Cells.ClearContents
Set driver = CreateObject("Selenium.ChromeDriver")
    'driver.AddArgument ("headless") '無頭視窗
    driver.Wait 1500
    driver.get "https://mis.twse.com.tw/stock/group.jsp?type=fixed&ex=tse&ind=TIDX#STATISTICS"

Set tbl6 = driver.findelementsbytag("table")(6)
  Set tby1 = tbl6.findelementsbytag("tbody")(1)
    Set tr2 = tby1.findelementsbytag("tr")(2)
      Set td2 = tr2.findelementsbytag("td")(3)
        Cells(1, 1) = td2.Text
End Sub

Sub 關閉子程序()
On Error Resume Next
If IsObject(driver) Then
driver.Quit
Set driver = Nothing
End If
End Sub

忘了說明
分解步驟版有個好處
就是可以多做 if isobject  + do loop+wait 判斷
另外不只可以判斷元素存在 也可以判斷值是否為空 或者判斷物件數量是否>1
避免有些網頁會慢慢才出現資料(這類網頁很常見 例如yahoo)

不過還有另外兩種類型也要小心
一種是 超出可視範圍外 會找不到元素(這種網頁不多)
一種是 要下拉網頁 才會跳出新元素(如FB)
這類網頁就要多花點功夫
通常國外論壇都有教 努力查 查的到
作者: t8899    時間: 2022-9-25 09:43

本帖最後由 t8899 於 2022-9-25 09:44 編輯

回復 10# singo1232001

請教看網頁原始碼?用什麼方法看,較容易找到標題??
/td /tr 這是一層一層???有無先後次序?如何快速知道要找的table 在第幾個??
找的技巧?
作者: singo1232001    時間: 2022-9-25 10:25

本帖最後由 singo1232001 於 2022-9-25 10:27 編輯

在你想找的網頁同一個位置
做兩次(按右鍵>檢查)

第一次是開啟 第二次是展開到你的元素
作者: t8899    時間: 2022-10-13 19:26

回復 10# singo1232001
請教我若同時要開第二視窗,要再增加 Set driver = CreateObject("Selenium.ChromeDriver")  這行 為
Set driver2 = CreateObject("Selenium.ChromeDriver")  ???
作者: t8899    時間: 2022-10-13 20:03

回復 12# singo1232001

https://mis.taifex.com.tw/futures/disclaimer
這網頁進入按"接受"怎麼寫?
作者: singo1232001    時間: 2022-10-13 20:07

本帖最後由 singo1232001 於 2022-10-13 20:14 編輯

回復 13# t8899

F8逐步測試

Sub test()
Set driver = CreateObject("Selenium.ChromeDriver")
driver.Get "https://www.google.com.tw/"
driver.ExecuteScript ("window.open()")
driver.SwitchToNextWindow
driver.Get "https://www.yahoo.com.tw/"
driver.Wait 1000
driver.Close
driver.Wait 1000
driver.SwitchToPreviousWindow
driver.Close
End Sub
作者: singo1232001    時間: 2022-10-13 20:11

回復 14# t8899


    Sub test2()
Set driver = CreateObject("Selenium.ChromeDriver")
driver.Get "https://mis.taifex.com.tw/futures/disclaimer/"
Set btnS = driver.findelementsbytag("button")
Debug.Print btnS(3).Text
btnS(3).Click
End Sub
作者: t8899    時間: 2022-10-14 06:23

本帖最後由 t8899 於 2022-10-14 06:41 編輯
回復  t8899


    Sub test2()
Set driver = CreateObject("Selenium.ChromeDriver")
driver.Get "h ...
singo1232001 發表於 2022-10-13 20:11

謝謝指導
1.我想加一個 假如不是這個網頁則跳過   (goto)
2.我用 driver.find_element_by_xpath(//*[@id="content"]/main/div[2]/div[2]/button[1].click())
錯誤停留紅色處??
作者: t8899    時間: 2022-10-14 06:40

本帖最後由 t8899 於 2022-10-14 06:43 編輯
回復  t8899

F8逐步測試

Sub test()
Set driver = CreateObject("Selenium.ChromeDriver")
driver ...
singo1232001 發表於 2022-10-13 20:07


driver.SwitchToNextWindow
這行的語法可否改成用"視窗的名字"切換? 或是直接對第幾個視窗做動作?
作者: quickfixer    時間: 2022-10-15 02:59

Sub test()
Set driver = CreateObject("Selenium.ChromeDriver")
driver.Get "http://forum.twbts.com/thread-23777-1-1.html"
w1 = driver.Title
driver.ExecuteScript ("window.open()")
driver.SwitchToNextWindow
driver.Get "https://www.yahoo.com.tw/"
w2 = driver.Title
driver.ExecuteScript ("window.open()")
driver.SwitchToNextWindow
driver.Get "https://www.mobile01.com/"
w3 = driver.Title
driver.Wait 2000
driver.SwitchToWindowByTitle w1
driver.Wait 5000
driver.SwitchToWindowByTitle w2
driver.Wait 5000
driver.SwitchToWindowByTitle w3
driver.Wait 5000
driver.Close
End Sub
作者: singo1232001    時間: 2022-10-15 03:06

本帖最後由 singo1232001 於 2022-10-15 03:16 編輯

回復 18# t8899

1
判斷網頁 可以用if 判斷式
試著用裡面的 物件存在狀態 or 物件數量 or 物件名稱 or 物件文字 or 網頁Title名稱(可能重複要看個案) 來判斷跳過
可以先下on error resume next 忽略錯誤
以下可供挑選判斷方式
啟用可以用isobject() =true
數量用.count>0
名稱用.attribute
文字用.text
網頁title名稱 用.title
上述文字可以搭配vba的instr like find 這列文字搜索的功能做判斷

2
xpath我不太常用 所以練的不熟 我習慣用tag抓位置 通常很高的高手會用xpath 或者運氣不錯剛好能用(該元素沒有後續才慢慢出現)
主要原因是 有時候 網頁不會一次性跳出來 他會慢慢跳  當然也可以用wait來等
也就是之前說到的狀況 用tag逐步找的方式,這種分解步驟可以慢慢判斷是否元素有出現了 再繼續下一步的判斷

3
印象可以 但不建議 怕多個視窗title重複 看個案使用  
下面是我查到的資料
語法好像是 driver.SwitchToWindowByTitle "Title名稱"     不過我沒實測過
https://stackoverflow.com/questions/52397268/how-do-i-switch-focus-to-a-new-window-using-selenium-vba
(可以下google關鍵字 vba selenium SwitchToNextWindow )找相關資料
通常我還是建議用driver.SwitchToNextWindow跳轉
跳過去如果不要了,也還是要還要用driver.SwitchToPreviousWindow跳回來
作者: checkout88    時間: 2022-10-15 16:12

回復 14# t8899


Sub test2()
    Set driver = CreateObject("Selenium.ChromeDriver")
    driver.Get "https://mis.taifex.com.tw/futures/disclaimer/"
    driver.findelementbyxpath("//*[@id=""content""]/main/div[2]/div[2]/button[1]").Click
End Sub
作者: checkout88    時間: 2022-10-15 16:25

回復 11# t8899

xpath 可以直接 copy, 不用一個一個找.

[attach]35322[/attach]
作者: t8899    時間: 2022-10-15 19:51

本帖最後由 t8899 於 2022-10-15 19:52 編輯
回復  t8899


Sub test2()
    Set driver = CreateObject("Selenium.ChromeDriver")
    driver.Ge ...
checkout88 發表於 2022-10-15 16:12

謝謝指導,用這個速度快多了
作者: t8899    時間: 2022-10-15 20:15

本帖最後由 t8899 於 2022-10-15 20:38 編輯
回復  t8899

F8逐步測試

Sub test()
Set driver = CreateObject("Selenium.ChromeDriver")
driver ...
singo1232001 發表於 2022-10-13 20:07


driver.SwitchToNextWindow
這個我想跳到另一個程序繼續延用,會失敗 ??
程序之前有用 Public DRIVER As Object
[attach]35323[/attach]
作者: singo1232001    時間: 2022-10-16 02:16

回復 24# t8899

最上面除了
publice driver as object
多加一行
public w1,w2


w1 跟w2 沒跟過去
目前看來是 ""
作者: singo1232001    時間: 2022-10-16 06:26

本帖最後由 singo1232001 於 2022-10-16 06:29 編輯

補充說明一下

用public 是全部的模組module 包括表單userform 都會吃到喔
   
如果其他模組也有用到 就用public

如果不想給其他模組Module 表單userform用的話

改用
dim driver as object
dim w1,w2

用dim 的話 同模組內的所有sub都能用 其他模組內的用不了

因為怕在其他模組的sub也有用到w1,w2 到時候衝突
作者: t8899    時間: 2022-10-16 07:35

回復  t8899

最上面除了
publice driver as object
多加一行
public w1,w2


w1 跟w2 沒跟過去
...
singo1232001 發表於 2022-10-16 02:16


試的結果 只能用 DRIVER.SwitchToPreviousWindow    ?
DRIVER.SwitchToWindowByTitle w1 '第一個交易所
DRIVER.SwitchToWindowByTitle w2 '第二個期交所
DRIVER.SwitchToNextWindow
這3個不行?
作者: singo1232001    時間: 2022-10-16 07:42

回復 27# t8899


建議你把程式碼貼出來好了

可能是沒有CLOSE掉八

或者需求說一下
作者: t8899    時間: 2022-10-16 09:29

回復  t8899


建議你把程式碼貼出來好了

可能是沒有CLOSE掉八

或者需求說一下
singo1232001 發表於 2022-10-16 07:42


解決了
我用public w1 , 又用 DIM w1 , 把dim w1 拿掉就好了
謝謝!
作者: t8899    時間: 2022-10-18 20:30

本帖最後由 t8899 於 2022-10-18 20:36 編輯

回復 28# singo1232001

Sub test()
Set DRIVER = CreateObject("Selenium.ChromeDriver")
DRIVER.Get "https://tw.stock.yahoo.com/quote/1101.TW"
Set td = DRIVER.FindElementByXPath("//*[@id=""qsp-overview-realtime-info""]/div[2]/div[2]/div/ul")
Cells.ClearContents
' td.AsTable.ToExcel Cells(1, 1)
End Sub
圖中框起來的灰色框框不是一個table ??
要如何以table方式匯入excel ?
[attach]35334[/attach]
作者: singo1232001    時間: 2022-10-19 10:43

本帖最後由 singo1232001 於 2022-10-19 10:54 編輯

回復 30# t8899

Sub test()
Set DRIVER = CreateObject("Selenium.ChromeDriver")
DRIVER.Get "https://tw.stock.yahoo.com/quote/1101.TW"
Cells.ClearContents
Set ID0 = DRIVER.FindElementByID("qsp-overview-realtime-info")
Set UL1 = ID0.FindElementsBytag("ul")(1)

sp = Split(UL1.Text, Chr(10))
Cells(1, 1).Resize(UBound(sp), 1) = Application.Transpose(sp)
End Sub

補充 上下漲跌的三角形 跟負號 上述並沒有做特別處理
若有需要就必須利用tag單獨找出來,依照上三角形 與 下三角形 個別比對修改正負數

[attach]35343[/attach]
作者: singo1232001    時間: 2022-10-19 11:03

回復 31# singo1232001


更正一下(單列 跟 雙列)

Sub test()
Set DRIVER = CreateObject("Selenium.ChromeDriver")
DRIVER.Get "https://tw.stock.yahoo.com/quote/1101.TW"
Cells.ClearContents
Set ID0 = DRIVER.FindElementByID("qsp-overview-realtime-info")
Set UL1 = ID0.FindElementsBytag("ul")(1)
'單列
sp = Split(UL1.Text, Chr(10))
Cells(1, 1).Resize(UBound(sp) + 1, 1) = Application.Transpose(sp)

'雙列
u2 = UBound(sp) / 2
ReDim ar(1 To u2, 1 To 2)
For i = 0 To UBound(sp) Step 2
w = w + 1
ar(w, 1) = sp(i)
ar(w, 2) = sp(i + 1)
Next
Cells(1, 3).Resize(UBound(ar), 2) = ar
End Sub
作者: singo1232001    時間: 2022-10-19 11:53

本帖最後由 singo1232001 於 2022-10-19 11:55 編輯

回復 32# singo1232001


另外給一些沒安裝過selenium的連結
http://forum.twbts.com/thread-23709-1-3.html




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