Board logo

標題: [發問] 用Selenium 抓上市行情即時資料 ??? [打印本頁]

作者: t8899    時間: 2022-10-19 07:19     標題: 用Selenium 抓上市行情即時資料 ???

https://mis.twse.com.tw/stock/gr ... type=all&ind=01
我想抓上市所有類股行情匯入excel  (右下角的頁數抓所有的頁數)
這個網頁好像可以用網頁位址後面的參數抓不同的資料?這要從何處看才能得到想要的資料?
我只看到ind=01==>水泥 各類別的號碼 ,是否有抓全部類別的號碼?,頁數可否一次抓所有??
作者: joey0415    時間: 2022-10-19 20:15

回復 1# t8899

https://mis.twse.com.tw/stock/api/getStockInfo.jsp?ex_ch=tse_1101.tw
https://mis.twse.com.tw/stock/api/getStockInfo.jsp?ex_ch=tse_1101.tw|tse_1102.tw
https://mis.twse.com.tw/stock/api/getStockInfo.jsp?ex_ch=tse_1101.tw|tse_1102.tw|tse_1103.tw
只要串接後方的值改一下就好
想加幾個就加幾個

若五秒鐘換一次用Selenium 應該會來不及

下面的結果應該用Split切一切就好

[attach]35345[/attach]
作者: singo1232001    時間: 2022-10-20 00:14

回復 2# joey0415


讚  

分享一下檔案
作者: t8899    時間: 2022-10-20 07:10

回復  joey0415


讚  

分享一下檔案
singo1232001 發表於 2022-10-20 00:14

謝謝指導
這個厲害
作者: t8899    時間: 2022-10-20 07:12

回復  t8899

https://mis.twse.com.tw/stock/ap ... p?ex_ch=tse_1101.tw
https://mis.tw ...
joey0415 發表於 2022-10-19 20:15



謝謝指導
是否有每個欄位資料各代表著什麼??
作者: singo1232001    時間: 2022-10-20 10:09

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

回復 5# t8899


    修正 陣列位置不足 與 資料判斷錯誤
作者: singo1232001    時間: 2022-10-20 10:40

回復 6# singo1232001


    新增股票自適應
作者: t8899    時間: 2022-10-20 12:15

本帖最後由 t8899 於 2022-10-20 12:25 編輯
回復  singo1232001


    新增股票自適應
singo1232001 發表於 2022-10-20 10:40

我對照一下行情,成交價在af欄,有些是空的??
原本網址傳回的資料有誤??

[attach]35355[/attach]
作者: singo1232001    時間: 2022-10-20 12:43

本帖最後由 singo1232001 於 2022-10-20 12:45 編輯

回復 8# t8899


    盤中有(31欄)  盤後有(36欄) 欄位數量不同  盤後的還會多出5~6列

   程序會自動適應多出的欄位

   我是直接設定上限50欄 所以都夠用
作者: t8899    時間: 2022-10-20 12:53

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


    盤中有(31欄)  盤後有(36欄) 欄位數量不同  盤後的還會多出5~6列

   程序會自動 ...
singo1232001 發表於 2022-10-20 12:43


我的意思,是原本傳回的資料是空的, 或許來源就有問題?
原本我問的網址 https://mis.twse.com.tw/stock/gr ... p;bp=0&type=all
我進去看有的也是空的 , 出現這"-" 符號
因為現在是盤中,都有資料
作者: t8899    時間: 2022-10-20 16:50

回復  t8899


    盤中有(31欄)  盤後有(36欄) 欄位數量不同  盤後的還會多出5~6列

   程序會自動 ...
singo1232001 發表於 2022-10-20 12:43

y 昨日收盤價
tv 單量
s 單量
b 買5檔價
g 買進5檔 量
a 賣5檔價
f 賣出5檔 量
v 總量
ot 時間
z 成交價
o 開盤
h 最高
L 最低
再請教我只要抓上面的欄位,程式碼要改那裡?
作者: singo1232001    時間: 2022-10-20 17:01

回復 11# t8899


    因為資料是一次性全部出來
就算用程序篩選也不會快多少
建議直接把不要的欄位隱藏就好了
作者: t8899    時間: 2022-10-20 19:09

回復  t8899


    因為資料是一次性全部出來
就算用程序篩選也不會快多少
建議直接把不要的欄位隱藏 ...
singo1232001 發表於 2022-10-20 17:01

好的,謝謝
作者: t8899    時間: 2022-10-21 09:59

回復  t8899


    因為資料是一次性全部出來
就算用程序篩選也不會快多少
建議直接把不要的欄位隱藏 ...
singo1232001 發表於 2022-10-20 17:01


Sub stopTime()  '關閉爬蟲
LTBL = False
Set 爬蟲.driver = Nothing
End Sub

請教停止抓取是否少了下面這行 ??
Application.OnTime lasttimevalue, "Tick.TimeTick", Schedule:=False
作者: t8899    時間: 2022-10-21 10:33

回復  t8899


    因為資料是一次性全部出來
就算用程序篩選也不會快多少
建議直接把不要的欄位隱藏 ...
singo1232001 發表於 2022-10-20 17:01


關檔後,有時會自動開啟檔案自動啟動 ???
作者: singo1232001    時間: 2022-10-21 14:13

回復 14# t8899


    是的 這段我忘了加上去了 感謝告知!

若這段沒寫 打開兩個excel以上時  因為計時程序還在背景繼續

就會再次把excel打開繼續執行

所以如同你說的方式處理
作者: singo1232001    時間: 2022-10-21 14:45

本帖最後由 singo1232001 於 2022-10-21 14:46 編輯

回復 16# singo1232001


    關於這份檔案 改動方向 盡可能避免雙開excel時出現異常(但還是有點小缺陷,並沒有完美避開)
1.第一次開啟檔案時 自動停止
2.關檔時 自動停止背景計時
3.程式碼都加上自身工作簿範圍set tbk  (避免不同檔案名稱 卻有相同名稱sub 造成程序誤判執行)

其他意外驚喜 不小心錄製巨集時 錄到了 ontime的 完整名稱路徑程式碼
方便在不同檔案同時執行時 產生衝突 提供了一條新的設定方法
不過 有許多變數 也需要增加範圍,重新設定
作者: t8899    時間: 2022-10-22 06:54

回復  t8899


    是的 這段我忘了加上去了 感謝告知!

若這段沒寫 打開兩個excel以上時  因為計時程 ...
singo1232001 發表於 2022-10-21 14:13

有些股票的欄位跑掉了(沒對齊)?不知是否是來源資料的問題?
[attach]35368[/attach]
作者: quickfixer    時間: 2022-10-23 02:41

本帖最後由 quickfixer 於 2022-10-23 02:46 編輯

回復 11# t8899

一定要Selenium?
這裡抄來的xmlhttp,速度快多了
引用來源
https://www.mobile01.com/topicdetail.php?f=511&t=4737630


[attach]35370[/attach]
自選
y 昨日收盤價
tv 單量
s 單量
b 買5檔價
g 買進5檔 量
a 賣5檔價
f 賣出5檔 量
v 總量
ot 時間
z 成交價
o 開盤
h 最高
L 最低

[attach]35369[/attach]
作者: t8899    時間: 2022-10-23 06:45

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

一定要Selenium?
這裡抄來的xmlhttp,速度快多了
引用來源




自選
y 昨日收盤價
...
quickfixer 發表於 2022-10-23 02:41

謝謝
不錯不錯,效率比Selenium  快,提供的原出處,能夠多學習
https://mis.twse.com.tw/stock/ap ... p?ex_ch=tse_2330.tw
交易所這個網址丟出的資料,有一個缺點 ,z(盤中即時成交價)幾乎都是"-",這是5秒照一次時,
當時沒有搓合資料?原網頁查詢也是一樣, 只能由5檔的買賣第一個價來參考,應該改為最後一筆成交資料,
不知有無其他網站能得到一樣的資料?
作者: t8899    時間: 2022-10-23 09:13

回復  t8899

自選
y 昨日收盤價
...
quickfixer 發表於 2022-10-23 02:41


https://mis.twse.com.tw/stock/gr ... ind=TIDX#STATISTICS
請教我想抓上面網頁table 5 To 6  xmlhttp的語去?
作者: singo1232001    時間: 2022-10-23 13:22

回復 21# t8899


    Sub test56()

Set driver = CreateObject("Selenium.ChromeDriver")

driver.get "https://mis.twse.com.tw/stock/group.jsp?ex=tse&currPage=0&ind=TIDX&bp=0&type=fixed"

Set tbls = driver.findelementsbytag("table")

tbls(5).astable.toexcel Cells(1, 1)

tbls(6).astable.toexcel Cells(1, 10)
End Sub
作者: t8899    時間: 2022-10-23 13:55

回復  t8899


    Sub test56()

Set driver = CreateObject("Selenium.ChromeDriver")

driver.g ...
singo1232001 發表於 2022-10-23 13:22


謝謝! 我是指 xmlhttp 的語法
對了,前面兄台寫的Selenium 語法 ,5871 這隻股票欄位不對,Split 的問題?
用 xmlhttp 語法是對的。
作者: t8899    時間: 2022-10-23 13:58

回復  t8899

一定要Selenium?
這裡抄來的xmlhttp,速度快多了
引用來源


自選
y 昨日收盤價
...
quickfixer 發表於 2022-10-23 02:41


我剛測試,超過170隻,就出現錯誤了
[attach]35371[/attach]
作者: singo1232001    時間: 2022-10-23 18:00

本帖最後由 singo1232001 於 2022-10-23 18:08 編輯

只有第一次執行比較久 因為開瀏覽器
    但之後都是秒讀唷 瀏覽器都在背景開著
作者: t8899    時間: 2022-10-23 20:15

本帖最後由 t8899 於 2022-10-23 20:18 編輯
只有第一次執行比較久 因為開瀏覽器
    但之後都是秒讀唷 瀏覽器都在背景開著
singo1232001 發表於 2022-10-23 18:00

我用150隻 有一隻3036 有問題
我用200隻  錯在  ReDim br(1 To UBound(sp) - 1, 0 To 50)  ??
最多只能幾隻?上市全部大約900多隻

[attach]35376[/attach]


[attach]35375[/attach]
作者: quickfixer    時間: 2022-10-23 20:37

最多只能幾隻?上市全部大約900多隻
t8899 發表於 2022-10-23 20:15


我試166支沒問題,第167支就出錯抓不到資料,你可能要分次下載

[attach]35377[/attach]
作者: quickfixer    時間: 2022-10-23 20:52

本帖最後由 quickfixer 於 2022-10-23 20:54 編輯

回復 27# quickfixer


    超過119支後面的股票就沒資料,但程式可以跑完
第167支,網頁出錯沒資料,所以程式也跟著錯
xmlhttp、Selenium 都一樣問題,是網站限制
作者: singo1232001    時間: 2022-10-23 22:53

回復 28# quickfixer


    大改
可能有很多bug 需要測試
作者: t8899    時間: 2022-10-24 06:03

回復  quickfixer


    大改
可能有很多bug 需要測試
singo1232001 發表於 2022-10-23 22:53

應該差不多了
有的全空白,應該是暫停交易,這是正常
用940隻可以正常跑完,速度感覺沒慢多少,還是有幾隻有問題??
[attach]35380[/attach]

[attach]35381[/attach]
作者: t8899    時間: 2022-10-24 06:10

回復  quickfixer


    超過119支後面的股票就沒資料,但程式可以跑完
第167支,網頁出錯沒資料,所以程 ...
quickfixer 發表於 2022-10-23 20:52

singo1232001兄 用 Selenium 最新修改940都可以正常跑完 ???
作者: t8899    時間: 2022-10-24 09:55

回復  quickfixer


    大改
可能有很多bug 需要測試
singo1232001 發表於 2022-10-23 22:53


抱歉,30樓的文作廢 (系統不給編輯刪除)
我剛又測試,應該是完美無缺了,感謝您熱心教導
作者: singo1232001    時間: 2022-10-24 12:45

本帖最後由 singo1232001 於 2022-10-24 12:59 編輯

回復 32# t8899


加入了自動更新selenium chromedriver的功能

    https://drive.google.com/drive/folders/1usKHGwtAZ1oJENT-DYzwrZH90HOo_6TV?usp=sharing
    (舊版的chromedrive.exe  測試更新會卡住狀況) 檔案過大 丟到雲端


另外 盤中高峰期 它們api 可能會會出現 卡超過15~20秒的情況
也可能是短期間 快速查詢(940/140 = 7次) 造成api異常
可能會被暫時ban IP 建議不要940全跑 或者 短期間跑太多次
作者: singo1232001    時間: 2022-10-24 13:08

回復 33# singo1232001
作者: singo1232001    時間: 2022-10-24 14:50

回復 34# singo1232001


    再優化一下
作者: t8899    時間: 2022-10-24 19:09

回復  singo1232001


    再優化一下
singo1232001 發表於 2022-10-24 14:50

辛苦了,感謝
作者: quickfixer    時間: 2022-10-25 02:35

本帖最後由 quickfixer 於 2022-10-25 02:43 編輯

回復 31# t8899


    xmlhttp,940支版,我是用120一組,140用在xml偶爾會失敗
[attach]35395[/attach]
可是有缺點,2327、1316,這2支全空白的
xmlhttp不會回傳資料(如下圖),msgarray直接空白,連股號都沒有
所以跟Selenium比起來會少2支,一樣查詢太快會擋ip,測試時被擋好幾次
我是覺的啦,要一直抓即時資料,改用股票軟體的dde會比較好
[attach]35393[/attach]
作者: t8899    時間: 2022-10-25 05:47

回復  t8899


    xmlhttp,940支版,我是用120一組,140用在xml偶爾會失敗

可是有缺點,2327、1316,這 ...
quickfixer 發表於 2022-10-25 02:35

2327、1316 這兩隻我查了一下,昨天是沒成交的,所以算正常
一次只能連167 隻,這個就沒辦法,網站的限制,一次連續連太多次會被鎖ip,這點我會注意,謝謝
作者: singo1232001    時間: 2022-10-25 17:47

回復 38# t8899


    這網站api好像有2種限制

1種是次數限制  我用兩支股票 手動複製網址 大概連續秒查30次(不到一分鐘) 就被踢
1種是數量限制  940隻(6~7次) 可能要40秒才能做一次  懷疑是 一分鐘限制查8次 或者 一分鐘內 限制不能超過1000隻 (會累計扣掉剩餘用量)
作者: t8899    時間: 2022-10-25 19:15

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


    這網站api好像有2種限制

1種是次數限制  我用兩支股票 手動複製網址 大概連續秒查 ...
singo1232001 發表於 2022-10-25 17:47

我發現這網站並沒有5秒更新一次,多少秒不太確定,應該不會低於30秒,所以設10秒抓一次,啟動後抓第2次,儲存格的值是不會動的
如何得知?
我是用台積電測,因為這種熱門股每秒都在搓合成交(從證商app的個股走勢明細可看出),看抓下來的v總量的值有沒有增加,就知道了
一次只能查166隻?這是quickfixer兄測的
還有詢問證交所 ===>盤中即時行情裡的成交價幾乎都是 "-"這個符號 ? 他的回答如下圖
[attach]35398[/attach]
作者: t8899    時間: 2022-10-26 10:13

回復  t8899


    這網站api好像有2種限制

1種是次數限制  我用兩支股票 手動複製網址 大概連續秒查 ...
singo1232001 發表於 2022-10-25 17:47

我又測了一下,網站5秒更一次 沒問題 (用1隻測)
我測99隻測第二次就會出現錯誤 ?很明顯有限制查的數量
作者: t8899    時間: 2022-10-28 07:17

回復  t8899


    這網站api好像有2種限制

1種是次數限制  我用兩支股票 手動複製網址 大概連續秒查 ...
singo1232001 發表於 2022-10-25 17:47

這個網站限制太多,最主要成交價八成是空的,只能看5檔裡的第一個買賣2選一無法確定實際成交價,只好捨棄

https://tw.stock.yahoo.com/class ... =2&exchange=TAI
這看起來是一個table? 我用 FindElementByXPath 找不到它的路徑?
[attach]35429[/attach]
作者: singo1232001    時間: 2022-10-28 18:32

本帖最後由 singo1232001 於 2022-10-28 18:42 編輯

回復 42# t8899


用bytag 而且這網頁我之前玩過

另外就是上面提到的 這網頁後面不會一次跑出來
只能用tag 跟畫面移動控制 來讓後面的跑出來
他的項目不是一般table 而是用class跑出來

需要用 find..s..tag+判斷+迴圈+等待 存在來逐步向內找更內層的元素 有點莫名的像是檔案總管一直開子資料夾那樣


檔案是5.6月左右寫得,能不能動 我不太清楚 也沒去修改
作者: t8899    時間: 2022-10-28 21:02

本帖最後由 t8899 於 2022-10-28 21:13 編輯
回復  t8899


用bytag 而且這網頁我之前玩過

另外就是上面提到的 這網頁後面不會一次跑出來
只能用 ...
singo1232001 發表於 2022-10-28 18:32

Sub kimo()
Application.ScreenUpdating = False
Set DRIVER = CreateObject("Selenium.ChromeDriver")
DRIVER.AddArgument ("headless") '無頭視窗
DRIVER.Get "https://tw.stock.yahoo.com/class-quote?sectorId=2&exchange=TAI"
Set dd = DRIVER.FindElementByXPath("//*[@id=""main-1-ClassQuotesTable-Proxy""]/div/div[3]/div/div/div[2]")
Range("a:K").Clearcontents
Range("a1:k1") = Array("股票名稱", "代號", "股價", "漲跌", "漲跌幅(%)", "開盤", "昨收", "最高", "最低", "成交量(張)", "時間")
a = split(dd.Text, Chr(10))
b = UBound(a)
   k = 11
   s = 2
   g = 1
For i = 0 To b
     If i = k Then
     k = k + 11
     s = s + 1
     g = 1
        End If
     Cells(s, g) = a(i)
    g = g + 1
    Next
End Sub
table 輸出較快?可惜它不是table
跌的下三角形沒抓到?如何直接改成"-"號輸出?
作者: Scott090    時間: 2023-4-16 23:12

回復 35# singo1232001


    此檔 seleniumdownload v9.zip->seleniumdownload v9.xlsm
   被 windows defender 檢出威脅 Trojan:O97M/Sadoca.C!ml
    請確認。

    謝謝
作者: singo1232001    時間: 2023-4-17 01:43

本帖最後由 singo1232001 於 2023-4-17 01:51 編輯

回復 45# Scott090


已測試 檔案沒問題
需要設定防毒 新增排除項目 把這個檔案排除在防毒之外

剛做了交叉測試

應該是下面這段sub 因為有調用到shell(CMD)  自動執行 下載+跟解壓縮+刪檔 就被被判定惡意程序
Sub updataSelenium()  '自動更新selenium
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
foler = Left(TempDrvFile, InStrRev(TempDrvFile, "\"))


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)


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


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"
   
    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 '                   "C:\Program Files\SeleniumBasic\chromedriver.zip", 2  'adSaveCreateOverWrite 'adSaveCreateOverWrite
            .Close
        End With
        
        '解壓縮        'C:\Program Files\SeleniumBasic
        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

上面這段是 查詢google chrome更新版本號
再從selenium官網 下再最新更新檔
自動更新chromedriver.exe更新的自動程序
並且刪除舊的chromedriver.exe
沒這段 就必須手動更新

也可以測試
若直接把這份檔案 丟到google雲端 開共享 刷新 也會跳旗子(有威脅性檔案)
如果你複製一份檔案 把上面那段都刪了 再丟到google雲端 就沒反應了

補充
若是下載後 打開不執行的情況 又是另一種情況
檔案>右鍵>內容> 解除封鎖
作者: Scott090    時間: 2023-4-17 08:26

回復 46# singo1232001

謝謝確認測試與指引
作者: Scott090    時間: 2023-8-20 14:55

回復 46# singo1232001

  請問大大,
    ChromeDriver 自115.0版 起, 期更新已不放在
          https://chromedriver.storage.googleapis.com/LATEST_RELEASE_
    而放在
          https://googlechromelabs.github.io/chrome-for-testing/#stable

   46樓的  程式該如何修飾:
Sub updataSelenium()  '自動更新selenium
   .........................
    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"
   
    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 '                   "C:\Program Files\SeleniumBasic\chromedriver.zip", 2  'adSaveCreateOverWrite 'adSaveCreateOverWrite
            .Close
        End With
        
        '解壓縮        'C:\Program Files\SeleniumBasic
        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   

    感謝
作者: Scott090    時間: 2023-8-20 15:48

回復 46# singo1232001

  請問大大,
    ChromeDriver 自115.0版 起, 期更新已不放在
          https://chromedriver.storage.googleapis.com/LATEST_RELEASE_
    而放在
          https://googlechromelabs.github.io/chrome-for-testing/#stable

   46樓的  程式該如何修飾:
Sub updataSelenium()  '自動更新selenium
   .........................
    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"
   
    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 '                   "C:\Program Files\SeleniumBasic\chromedriver.zip", 2  'adSaveCreateOverWrite 'adSaveCreateOverWrite
            .Close
        End With
        
        '解壓縮        'C:\Program Files\SeleniumBasic
        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   

    感謝
作者: singo1232001    時間: 2023-8-20 19:38

本帖最後由 singo1232001 於 2023-8-20 19:47 編輯

回復 49# Scott090

本人不是很專業 自己也沒把握可以100%沒問題
加上不知道之後有那些網址與語法是固定的
所以可以先將就用看看

    Sub updataSelenium()
'由於selenium有可能會安裝在windows下兩個其中一個資料夾中 所以要先找出資料夾位置 (mac目前未考慮)
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, "\")) '取得 資料夾路徑 與 chromedrive.exe 路徑

'獲取當前chromedriver版本前兩碼 例: 117.0
Set oShell = CreateObject("wscript.shell")
errcode = oShell.Exec(TempDrvFile & " --version").StdOut.ReadAll
verarr = Split(errcode, " ")
chrdrv = verarr(1)
dotsarr2 = Split(chrdrv, ".")

'獲取chrome當前瀏覽器版本號     例: 117.0
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 與 chrome瀏覽器 兩個版本號, 相同(不更新) ; 不同(上官網查瀏覽器最新版本號 並繼續下載解壓取代)
leftchrdrv = dotsarr2(0) & dotsarr2(1)
If leftchrver = leftchrdrv Then Exit Sub

'到官網api獲取版本資訊 並拆解資訊 該資訊為json格式 並獲得當前瀏覽器可用的chromedriver版本號
'本json拆法為特製 不符合正規json 不知道未來的格式會不會變 因為不想引用額外物件
Url = "https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone.json"
Call objHTTP.Open("GET", Url, False)
Call objHTTP.Send("")
version_number = objHTTP.responseText
v0 = Split(version_number, ",""milestones"":{")
v1 = Split(v0(1), "},")
For i = 0 To UBound(v1)
v1(i) = Replace(v1(i), """", "")
v1(i) = Replace(v1(i), ":{milestone:", ",")
v1(i) = Replace(v1(i), ",version:", ",")
v1(i) = Replace(v1(i), ",revision:", ",")
v1(i) = Replace(v1(i), "}}}", ",")
Next
ReDim v2(UBound(v1))
For i = 0 To UBound(v1): v2(i) = Split(v1(i), ","): Next
For i = 0 To UBound(v2)
If v2(i)(0) = dotsarr(0) Then: version_number = v2(i)(2): Exit For
Next

'生成連結網址  (另須注意選擇作業系統位元 在下方cmd處 也有需要修改的部分)  不知道未來網址會不會變
'download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/linux64/chromedriver-linux64.zip"
'download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/mac-x64/chromedriver-mac-x64.zip"
'download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/win32/chromedriver-win32.zip"
download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/win64/chromedriver-win64.zip"
    Call objHTTP.Open("GET", download_url, False)
    Call objHTTP.Send("")

        Set fileStream = CreateObject("ADODB.Stream")  '使用adodb.stream 接受檔案
        With fileStream
            .Open
            .Type = 1 'adTypeBinary
            .Write objHTTP.responseBody
            .Position = 0
            .SaveToFile foler & "chromedriver.zip", 2 '  下載檔案到selenium資料夾    ' 2  adSaveCreateOverWrite
            .Close
        End With
        
        '使用shell+cmd殺舊的檔案   kill的方式被微軟封了
        Set oApp = CreateObject("Shell.Application")
        cmdCommand = "cmd /c del " & foler & "chromedriver.exe"     '使用cmd刪除檔案 cmd /c del "path"
        Call Shell(cmdCommand, vbHide)                             '殺掉舊的chromedriver.exe
        cmdCommand = "cmd /c del " & foler & "LICENSE.chromedriver"
        Call Shell(cmdCommand, vbHide)                             '殺掉舊的LICENSE.chromedriver
            '若沒殺成功 該程序沒關閉 無法刪除時 將執行佇列中的檔案關閉  'cmd /c taskkill /F /IM chromedriver.exe 是殺佇列
            If Dir(foler & "chromedriver.exe") <> "" Then
            cmdCommand = "cmd /c taskkill /F /IM chromedriver.exe && cmd /c del " & foler & "chromedriver.exe"  '殺掉舊的chromedriver.exe
            Call Shell(cmdCommand, vbHide)
            End If
            If Dir(foler & "LICENSE.chromedriver") <> "" Then
            cmdCommand = "cmd /c taskkill /F /IM LICENSE.chromedriver && cmd /c del " & foler & "LICENSE.chromedriver"  '殺掉舊的LICENSE.chromedriver
            Call Shell(cmdCommand, vbHide)
            End If
            
        '將新的chromedriver.exe解壓縮到資料夾中  16是強制取代選項 注意壓縮檔內的檔名 會因系統位元不同資料夾不同
        oApp.Namespace(foler).CopyHere _
            oApp.Namespace(foler & "chromedriver.zip\chromedriver-win64").items, 16

End Sub
作者: Scott090    時間: 2023-8-20 20:37

回復 50# singo1232001


    感謝大大用心地協助。
    Google Chrome 常常在改版本實 在是捆擾,它的 雲端硬碟 ChromeDriveFs 也是。
作者: singo1232001    時間: 2023-8-20 21:26

回復 51# Scott090

由於有人不知道要去安裝主插件 所以也把插件安裝流程寫進去了
https://github.com/florentbr/SeleniumBasic/releases
SeleniumBasic v2.0.9.0.exe
第一次安裝完成後,必須在開始>執行selenium中的start chrome
等待錯誤彈出並確定,將自動安裝.net framwork 安裝完畢後重開機
再執行本程序則可以更新版本


Sub updataSelenium()
'由於selenium有可能會安裝在windows下兩個其中一個資料夾中 所以要先找出資料夾位置 (mac目前未考慮)
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, "\")) '取得 資料夾路徑 與 chromedrive.exe 路徑
'若未安裝selenium 2.0.9.0 將會跳轉到github網站 請自行下載安裝
If foler = "" Then
    msg = "(請拍照抓圖本畫面)" & vbCrLf
    msg = msg & "找不到selenium插件資料夾 需至網站" & vbCrLf & "https://github.com/florentbr/SeleniumBasic/releases"
    msg = msg & vbCrLf & "下載安裝 SeleniumBasic v2.0.9.0.exe" & vbCrLf & vbCrLf & "是否直接前往?"
    msg = msg & vbCrLf & vbCrLf & "注意後續步驟:" & vbCrLf & "第一次安裝完成後,必須在開始>執行selenium中的start chrome" & vbCrLf
    msg = msg & "等待錯誤彈出並確定,將自動安裝.net framwork 安裝完畢後重開機" & vbCrLf & "再執行本程序則可以更新版本"
    x = MsgBox(msg, vbYesNo, "未安裝插件")
    If x = 6 Then
    edgePath1 = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
    edgePath2 = "C:\Program Files\Microsoft\Edge\Application\msedge.exe"
    If Dir(edgePath1) <> "" Then edgePath = edgePath1
    If Dir(edgePath2) <> "" Then edgePath = edgePath2
    edgePath = """" & edgePath & """" & " https://github.com/florentbr/SeleniumBasic/releases"
    Call Shell(edgePath, vbNormalFocus)
    End If
Exit Sub
End If

'獲取當前chromedriver版本前兩碼 例: 117.0
Set oShell = CreateObject("wscript.shell")
errcode = oShell.Exec(TempDrvFile & " --version").StdOut.ReadAll
verarr = Split(errcode, " ")
chrdrv = verarr(1)
dotsarr2 = Split(chrdrv, ".")

'獲取chrome當前瀏覽器版本號     例: 117.0
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 與 chrome瀏覽器 兩個版本號, 相同(不更新) ; 不同(上官網查瀏覽器最新版本號 並繼續下載解壓取代)
leftchrdrv = dotsarr2(0) & dotsarr2(1)
If leftchrver = leftchrdrv Then Exit Sub

'到官網api獲取版本資訊 並拆解資訊 該資訊為json格式 並獲得當前瀏覽器可用的chromedriver版本號
'本json拆法為特製 不符合正規json 不知道未來的格式會不會變 因為不想引用額外物件
Url = "https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone.json"
Call objHTTP.Open("GET", Url, False)
Call objHTTP.Send("")
version_number = objHTTP.responseText
v0 = Split(version_number, ",""milestones"":{")
v1 = Split(v0(1), "},")
For i = 0 To UBound(v1)
v1(i) = Replace(v1(i), """", "")
v1(i) = Replace(v1(i), ":{milestone:", ",")
v1(i) = Replace(v1(i), ",version:", ",")
v1(i) = Replace(v1(i), ",revision:", ",")
v1(i) = Replace(v1(i), "}}}", ",")
Next
ReDim v2(UBound(v1))
For i = 0 To UBound(v1): v2(i) = Split(v1(i), ","): Next
For i = 0 To UBound(v2)
If v2(i)(0) = dotsarr(0) Then: version_number = v2(i)(2): Exit For
Next

'生成連結網址  (另須注意選擇作業系統位元 在下方cmd處 也有需要修改的部分)  不知道未來網址會不會變
'download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/linux64/chromedriver-linux64.zip"
'download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/mac-x64/chromedriver-mac-x64.zip"
'download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/win32/chromedriver-win32.zip"
download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/win64/chromedriver-win64.zip"
    Call objHTTP.Open("GET", download_url, False)
    Call objHTTP.Send("")

        Set fileStream = CreateObject("ADODB.Stream")  '使用adodb.stream 接受檔案
        With fileStream
            .Open
            .Type = 1 'adTypeBinary
            .Write objHTTP.responseBody
            .Position = 0
            .SaveToFile foler & "chromedriver.zip", 2 '  下載檔案到selenium資料夾    ' 2  adSaveCreateOverWrite
            .Close
        End With
        
        '使用shell+cmd殺舊的檔案   kill的方式被微軟封了
        Set oApp = CreateObject("Shell.Application")
        cmdCommand = "cmd /c del " & foler & "chromedriver.exe"     '使用cmd刪除檔案 cmd /c del "path"
        Call Shell(cmdCommand, vbHide)                             '殺掉舊的chromedriver.exe
        cmdCommand = "cmd /c del " & foler & "LICENSE.chromedriver"
        Call Shell(cmdCommand, vbHide)                             '殺掉舊的LICENSE.chromedriver
            '若沒殺成功 該程序沒關閉 無法刪除時 將執行佇列中的檔案關閉  'cmd /c taskkill /F /IM chromedriver.exe 是殺佇列
            If Dir(foler & "chromedriver.exe") <> "" Then
            cmdCommand = "cmd /c taskkill /F /IM chromedriver.exe && cmd /c del " & foler & "chromedriver.exe"  '殺掉舊的chromedriver.exe
            Call Shell(cmdCommand, vbHide)
            End If
            If Dir(foler & "LICENSE.chromedriver") <> "" Then
            cmdCommand = "cmd /c taskkill /F /IM LICENSE.chromedriver && cmd /c del " & foler & "LICENSE.chromedriver"  '殺掉舊的LICENSE.chromedriver
            Call Shell(cmdCommand, vbHide)
            End If
            
        '將新的chromedriver.exe解壓縮到資料夾中  16是強制取代選項 注意壓縮檔內的檔名 會因系統位元不同資料夾不同
        oApp.Namespace(foler).CopyHere _
            oApp.Namespace(foler & "chromedriver.zip\chromedriver-win64").items, 16

End Sub
作者: Scott090    時間: 2023-8-21 10:38

回復 52# singo1232001

    謝謝大大的細心與貼心。
       SeleniumBasic 的版本好久沒更新了, 一直停留在  v2.0.9.0。

    測試了 #52 樓的程式, 確實成功的更新到 "Stable" 內的 "116.0"的版本。
作者: Scott090    時間: 2023-8-21 11:05

回復 52# singo1232001

   再請教 大大, 下一程式如何填加功能取得 "資料時間 : 2023/08/21 10:44", 謝謝
  http://forum.twbts.com/viewthread.php?tid=23777&page=4
   Sub Test()
    Dim Driver As New Selenium.ChromeDriver
    Dim ID0 As Object, UL1
    Dim sp, u2%, ar(), i%, w%
    Dim sh As Worksheet
   
    Cells.ClearContents
   
    Set Driver = CreateObject("Selenium.ChromeDriver")
    If Driver Is Nothing Then opDriver
    Driver.AddArgument ("headless")     '不顯示WebPage
'    Driver.Start
    Driver.Get "https://tw.stock.yahoo.com/quote/1101.TW"
   
    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    時間: 2023-8-21 11:20

Driver.Get "https://tw.stock.yahoo.com/quote/1101.TW"

   Do: Set ID0 = Driver.findelementsbyID("main-0-QuoteHeader-Proxy")
        If ID0.Count > 0 Then Exit Do
        Loop
   Do: Set spans = ID0(1).findelementsbytag("span")
        If spans.Count > 0 Then Exit Do
        Loop
    For Each Z In spans
    If Z.Text Like "*開盤*更新*" Then
    時間 = Replace(Z.Text, "開盤 | ", "")
    時間 = "資料時間:" & Replace(時間, " 更新", "")
    Exit For
    End If
    Next
作者: Scott090    時間: 2023-8-21 15:43

回復 55# singo1232001

  經測試後, 時間變數是空白, 不知問題在哪裡
  請 大大 再看看
  謝謝
作者: singo1232001    時間: 2023-8-21 19:51

回復 56# Scott090

Driver.Get "https://tw.stock.yahoo.com/quote/1101.TW"

   Do: Set ID0 = Driver.findelementsbyID("main-0-QuoteHeader-Proxy")
        If ID0.Count > 0 Then Exit Do
        Loop
   Do: Set spans = ID0(1).findelementsbytag("span")
        If spans.Count > 0 Then Exit Do
        Loop
    For Each Z In spans
    If Z.Text Like "*盤*更新*" Then
    sp = Split(Z.Text, " ")
    時間 = "資料時間:" & sp(2) & " " & sp(3)
    Exit For
    End If
    Next
作者: Scott090    時間: 2023-8-21 20:50

回復 57# singo1232001


    有得到正確的資料了:
         時間 =  "資料時間:2023/08/21 14:30"

    非常感恩
作者: t8899    時間: 2023-10-12 06:08

回復 52# singo1232001
path1 = "C:\Users\" & Environ$("username") & "\AppData\Local\SeleniumBasic\Chromedriver.exe"
1.我是裝在上面的資料夾?沒抓到?我就把"C:\Users\" & Environ$("username") & "直接換成實際的路徑才抓到 ?
2.下載有成功, 也有解壓縮,但zip檔沒刪除 ?
作者: singo1232001    時間: 2023-10-12 21:57

回復 59# t8899


    1. 可以  或者自己設個PATH3 ,再DIR 做判斷
2.若不影響  那就放著不管他就好 應該是我沒寫刪除ZIP的功能
作者: singo1232001    時間: 2023-11-8 12:08

本帖最後由 singo1232001 於 2023-11-8 12:10 編輯

回復 59# t8899


    一個不算bug的小bug回報 需要注意一下

遇到的狀況
當chrome119版時  但 chromedriver 還停留在 118版並沒有更新

原因在於
之前版本不同時 chromedriver會完全無法開啟chrome 並進入updateselenium自動更新程序

但現在版本不同時 "一樣能啟動瀏覽器,但會出現一些網頁元素無法find獲取跟點擊的bug" 例如彈出類型的 或者 javascript類型的 動態生成元素
會無法正確操作

所以我們需要增加一些判斷並 call updateselenium 這段功能  
必須在各位自己寫的主程序中 去新增判斷是否要重新檢查 瀏覽器與插件的版本號
例如:重新開啟次數過多 或者失敗超過幾次 必須 call updateselenium

我目前遇到的是 瀏覽器正常開啟  但某個元素與按鈕點不下去
我增加一些失敗錯誤次數判斷  問題已解決 而之前提供的更新程序 不需要修改
作者: t8899    時間: 2023-11-9 06:19

[quote]回復  t8899


    一個不算bug的小bug回報 需要注意一下

遇到的狀況
當chrome119版時  但 chromed ...
singo1232001 發表於 2023-11-8 12:08 [/quot
感謝提醒,也謝謝您的指導
作者: singo1232001    時間: 2024-2-23 18:38

回復 62# t8899

chromeDrive的檔案下載網址改了

要改下面那個
'download_url = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & version_number & "/win64/chromedriver-win64.zip"
download_url = "https://storage.googleapis.com/chrome-for-testing-public/" & version_number & "/win64/chromedriver-win64.zip"
作者: t8899    時間: 2024-2-24 09:26

回復  t8899

chromeDrive的檔案下載網址改了

要改下面那個
'download_url = "https://edgedl.me.gv ...
singo1232001 發表於 2024-2-23 18:38


謝謝告知




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