返回列表 上一主題 發帖

[發問] 用Selenium 抓上市行情即時資料 ???

回復  t8899


    這網站api好像有2種限制

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

我又測了一下,網站5秒更一次 沒問題 (用1隻測)
我測99隻測第二次就會出現錯誤 ?很明顯有限制查的數量

TOP

回復  t8899


    這網站api好像有2種限制

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

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

https://tw.stock.yahoo.com/class ... =2&exchange=TAI
這看起來是一個table? 我用 FindElementByXPath 找不到它的路徑?

TOP

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

回復 42# t8899


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

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

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


檔案是5.6月左右寫得,能不能動 我不太清楚 也沒去修改

網頁爬蟲v1.zip (52 KB)

TOP

本帖最後由 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
跌的下三角形沒抓到?如何直接改成"-"號輸出?

TOP

回復 35# singo1232001


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

    謝謝

TOP

本帖最後由 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雲端 就沒反應了

補充
若是下載後 打開不執行的情況 又是另一種情況
檔案>右鍵>內容> 解除封鎖

TOP

回復 46# singo1232001

謝謝確認測試與指引

TOP

回復 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   

    感謝

TOP

回復 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   

    感謝

TOP

本帖最後由 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

TOP

        靜思自在 : 能付出愛心就是福,能消除煩惱就是慧。
返回列表 上一主題