Board logo

標題: [發問] 無法用外部資料匯入的網站能用VBA讀取資料嗎? [打印本頁]

作者: 小俠客    時間: 2014-6-5 11:39     標題: 無法用外部資料匯入的網站能用VBA讀取資料嗎?

近日在做一些追縱研究,需要定期到下面網站讀取所有公司的名稱、地址和地址類型
https://eservices.customs.gov.hk/MSOS/wsrh/001s1?searchBy=B

我試過用「外部資料匯入」和錄製巨集來處理,但EXCEL看來讀不到那些TABLE的資料。
請問VBA能夠處理嗎?謝謝大家。
作者: 小俠客    時間: 2014-6-5 13:26

  1. Sub GetData()


  2. URL = "https://eservices.customs.gov.hk/MSOS/wsrh/001s1?searchBy=A"

  3. With CreateObject("InternetExplorer.Application")
  4.   .Visible = True     '  是否顯示 IE
  5.   .Navigate URL

  6. Do While .ReadyState <> 4 Or .Busy

  7. DoEvents

  8. Loop

  9. xlHtm = .Document.body.innerHTML
  10. End With

  11. End Sub
複製代碼
我試了用CREATEOBJECT,但有些資料多過一頁時,請問如何轉頁?
作者: GBKEE    時間: 2014-6-7 16:48

本帖最後由 GBKEE 於 2014-6-7 18:23 編輯

回復 2# 小俠客
試試看
  1. Option Explicit
  2. Const FormDLL = "FM20.DLL"
  3. Sub IE下一頁()
  4.     Dim URL As String, A As Object, Table As Object, i As Integer, pubSrch As Object, Pages As Integer
  5.     Dim Sh As Worksheet, B As String
  6.     Set_FormDLL
  7.     Set Sh = ActiveSheet
  8.     Sh.Cells.Clear
  9.     URL = "https://eservices.customs.gov.hk/MSOS/wsrh/001s1?searchBy=A"
  10.     With CreateObject("InternetExplorer.Application")
  11.         .Visible = True     '  是否顯示 IE
  12.         .Navigate URL
  13.         Do While .ReadyState <> 4 Or .Busy
  14.             DoEvents
  15.         Loop
  16.         Set A = .Document.getElementsByTAGName("A")
  17.         For i = 0 To A.Length - 1
  18.             If A(i).innertext = "ALL" Then
  19.                 A(i).Click
  20.                 Exit For
  21.             End If
  22.         Next
  23.         Do While .ReadyState <> 4 Or .Busy
  24.             DoEvents
  25.         Loop
  26.         Do
  27.             Set A = .Document.getElementsByTAGName("TD")
  28.         Loop Until Not A Is Nothing And A.Length = 84
  29.         For i = 0 To A.Length - 1
  30.             If A(i).ID = "grid-table-pubSrch_center" Then
  31.                 Pages = Val(Replace(A(i).innertext, "Page  of ", ""))        '總頁數
  32.             End If
  33.             If A(i).ID = "next_grid-table-pubSrch" Then Set pubSrch = A(i)                         '下一頁按鍵
  34.         Next
  35.         Set Table = .Document.getElementsByTAGName("table")
  36.         For i = 1 To Pages
  37.             If i >= 2 Then
  38.                 pubSrch.Click
  39.                 Do While .ReadyState <> 4 Or .Busy:        Loop
  40.                 Set Table = .Document.getElementsByTAGName("table")
  41.                 Do:  Loop Until B <> Table(6).outerHTML
  42.             End If
  43.             Ep Sh, Table(6).outerHTML
  44.             B = Table(6).outerHTML
  45.         Next
  46.         .Quit
  47.     End With
  48.     With Sh
  49.         .Cells.WrapText = False
  50.         Intersect(Range("b:b").SpecialCells(xlCellTypeBlanks).EntireRow, .Range("c:c").SpecialCells(xlCellTypeBlanks).EntireRow).Delete
  51.         .Cells.EntireRow.AutoFit
  52.         .Range("a1").Activate
  53.     End With
  54.     Remove_FormDLL

  55. End Sub
  56. Private Sub Set_FormDLL()   '新增引用 Microsoft Forms 2.0 Object Library
  57.     On Error Resume Next
  58.     ThisWorkbook.VBProject.References.AddFromFile "C:\windows\system32\" & FormDLL
  59.   '  On Error GoTo 0
  60. End Sub
  61. Private Sub Remove_FormDLL() '刪除引用 Microsoft Forms 2.0 Object Library
  62.     Dim D As Object
  63.     For Each D In ThisWorkbook.VBProject.References
  64.         If UCase(D.fullpath) Like "*" & FormDLL Then
  65.             ThisWorkbook.VBProject.References.Remove D
  66.         End If
  67.     Next
  68. End Sub
  69. Private Sub Ep(Sh As Worksheet, S As String)
  70.     Dim D As New DataObject, E As Shape, FormDLL As String ', Rng As Range
  71.     'DataObject 物件 在進行轉換動作時,做為格式化文字資料的暫存區域。其也可以暫存和儲存在 DataObject 的文字片段相關的格式。
  72.     '宣告 Dim D As New DataObject '須在工具-> 設定引用項目加入 新增引用 Microsoft Forms 2.0 Object Library ,專案 加入一表單即可
  73.     With D
  74.         .SetText S
  75.         .PutInClipboard
  76.         With Sh
  77.              .Cells(.Rows.Count, "b").End(xlUp).Offset(1, -1).Select
  78.             .PasteSpecial Format:="Unicode 文字"
  79.         End With
  80.     End With
  81. End Sub
複製代碼

作者: 小俠客    時間: 2014-6-10 12:07

本帖最後由 小俠客 於 2014-6-10 12:08 編輯

謝謝GBKEE大大,好像已經可以了!
太利害,我再試試看。
代碼有很多看不懂的東西,希望仔細看後能弄清楚當中原理,謝謝。
作者: 小俠客    時間: 2014-6-10 14:16

本帖最後由 小俠客 於 2014-6-10 14:19 編輯

對不起,關於GBKEE大分享的CODING,我有些疑問:

1) "FM20.DLL" 是Microsoft Forms 2.0 Object Library ,但如果我想了解它的功能和使用方便,應該如何入手?

2) "grid-table-pubSrch_center"、"next_grid-table-pubSrch",這些keyword是如何找出來?我在原始檔找不到......

3) 我對CreateObject("InternetExplorer.Application")的操作不了解,有沒有相關資料可以參考?

謝謝大家
謝謝。
作者: GBKEE    時間: 2014-6-12 08:33

回復 5# 小俠客
1) "FM20.DLL" 是Microsoft Forms 2.0 Object Library ,但如果我想了解它的功能和使用方便,應該如何入手?
Private Sub Ep(Sh As Worksheet, S As String)
  Dim D As New DataObject ,VBA中要引用項目Microsoft Forms 2.0 Object Library
活頁簿 中只要有使用到 MSForms的控制項 VBA都會自動地引用Microsoft Forms 2.0 Object Library

2) "grid-table-pubSrch_center"、"next_grid-table-pubSrch",這些keyword是如何找出來?我在原始檔找不到......
請參考 Private Sub 網頁的元素()

3) 我對CreateObject("InternetExplorer.Application")的操作不了解,有沒有相關資料可以參考?
Google CreateObject("InternetExplorer.Application") 看看
作者: 小俠客    時間: 2014-6-12 15:55

回復  小俠客
1) "FM20.DLL" 是Microsoft Forms 2.0 Object Library ,但如果我想了解它的功能和使用方便 ...
GBKEE 發表於 2014-6-12 08:33




有點弄不清楚,版大可否簡介「Microsoft Forms 2.0 Object Library」在此程式的作用?
是把網頁上的資料當成FORM來讀取嗎?
作者: GBKEE    時間: 2014-6-14 16:47

本帖最後由 GBKEE 於 2014-6-14 20:44 編輯

回復 7# 小俠客
把網頁上的資料當成FORM來讀取


[attach]18505[/attach]


檔案下載後,如圖示匯入 表單



[attach]18504[/attach]
作者: 小俠客    時間: 2014-6-20 16:03

回復  小俠客





檔案下載後,如圖示匯入 表單
GBKEE 發表於 2014-6-14 16:47



    經過數天的研究,我開始有點了解
但我對大大之前提供的代碼仍然不太清晰,可以請你稍作解譯嗎?
  1.         Do
  2.             Set A = .Document.getElementsByTAGName("TD")
  3.         Loop Until Not A Is Nothing And A.Length = 84
複製代碼
我查到getElementsByTAGName("TD")是指「返回帶有指定標簽名的對象集合」
即是A = 「返回帶有TD標簽名的對象集合」
A.Length 是指這個集合的總數
但我參考 「Private Sub 網頁的元素()」
我發現只有54個TD ,為什麼大大會寫84?(A.length真的是84,只是我不明白為何是84,而且如何得知是84)

另外,如果我們是希望從"TD"集合中找出 A(i).ID = "grid-table-pubSrch_center"
  1.         Do
  2.             Set A = .Document.getElementsByTAGName("TD")
  3.         Loop Until Not A Is Nothing And A.Length = 84
複製代碼
可不可以寫成
  1. Set A = .Document.getElementsByTAGName("TD")
複製代碼
因為我不太明白這個LOOP的作用
謝謝大大指教
作者: GBKEE    時間: 2014-6-20 21:03

回復 9# 小俠客
  1. Do
  2.             Set A = .Document.getElementsByTAGName("TD")
  3.         Loop Until Not A Is Nothing And A.Length = 84
  4.         MsgBox A.Length  '可看看倒底是多少
複製代碼
Set A = .Document.getElementsByTAGName("TD")
不放在 Do   Loop 迴圈也可以,
但因網頁資料下載速度比程式速度執行慢,導致  A Is Nothing
只得用  Do   Loop  直到 Not A Is Nothing
作者: 小俠客    時間: 2014-6-23 09:20

回復  小俠客 Set A = .Document.getElementsByTAGName("TD")
不放在 Do   Loop 迴圈也可以,
但因網頁資料 ...
GBKEE 發表於 2014-6-20 21:03


原來如此,因為我是用「逐行執行」的方式研究代碼,所以比較沒有這個問題,實際運行確需要作這個checking。
那麼a.length = 84又是甚麼意思?

A = 「返回帶有TD標簽名的對象集合」
A.Length 是指這個集合的總數
但我參考 「Private Sub 網頁的元素()」
我發現只有54個TD ......
作者: GBKEE    時間: 2014-6-23 09:42

本帖最後由 GBKEE 於 2014-6-23 09:43 編輯

回復 11# 小俠客
  1. '網頁搜尋結果: 0 記錄
  2. Option Explicit
  3. Sub IE下一頁()
  4.     Dim url As String, a As Object, Table As Object, i As Integer, pubSrch As Object, Pages As Integer
  5.     Dim Sh As Worksheet, B As String, E
  6.     Set Sh = ActiveSheet
  7.     Sh.Cells.Clear
  8.     '************************************
  9.     url = "https://eservices.customs.gov.hk/MSOS/wsrh/001s1?"  
  10.    'url = "https://eservices.customs.gov.hk/MSOS/wsrh/001s1?"searchBy=A"  '網頁有資料
  11.     '************************************
  12.     With CreateObject("InternetExplorer.Application")
  13.         .Visible = True     '  是否顯示 IE
  14.         .Navigate url
  15.         Do While .ReadyState <> 4 Or .Busy
  16.             DoEvents
  17.         Loop
  18.         Do
  19.             Set a = .Document.getElementsByTAGName("TD")
  20.         Loop Until Not a Is Nothing 'And a.Length = 84
  21.         On Error Resume Next
  22.         With Sh
  23.             For i = 0 To a.Length - 1
  24.                 .Cells(i + 1, "A") = i
  25.                 .Cells(i + 1, "B") = a(i).Type
  26.                 .Cells(i + 1, "C") = a(i).ID
  27.                 .Cells(i + 1, "D") = a(i).InnerText
  28.                 .Cells(i + 1, "E") = a(i).Value
  29.             Next
  30.             
  31.         End With
  32.         
  33.         .Quit
  34.     End With
  35.     MsgBox "getElementsByTAGName(""TD"") 合計 " & a.Length
  36. End Sub
複製代碼
[attach]18541[/attach]




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