【问题标题】:Scraping a table from a website using VBA使用 VBA 从网站抓取表格
【发布时间】:2019-02-23 22:23:01
【问题描述】:

我是 VBA 和网站的新手。

我正在尝试从下面的网站中提取数据(表格)以用于 VBA 代码。

http://www.bkam.ma/Marches/Principaux-indicateurs/Marche-obligataire/Marche-des-bons-de-tresor/Marche-secondaire/Taux-de-reference-des-bons-du-tresor?date=13%2F02%2F2019&block=e1d6b9bbf87f86f8ba53e8518e882982#address-c3367fcefc5f524397748201aee5dab8-e1d6b9bbf87f86f8ba53e8518e882982

我尝试创建一个 Internet Explorer 浏览器:

Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")

With appIE
    .Navigate "http://www.bkam.ma/Marches/Principaux-indicateurs/Marche-obligataire/Marche-des-bons-de-tresor/Marche-secondaire/Taux-de-reference-des-bons-du-tresor?date=13%2F02%2F2019&block=e1d6b9bbf87f86f8ba53e8518e882982#address-c3367fcefc5f524397748201aee5dab8-e1d6b9bbf87f86f8ba53e8518e882982"
    .Visible = True
End With

Do While appIE.Busy
    DoEvents
Loop

然后,我尝试使用 ID 或标记名属性来获取数据

Set val = appIE.document.getElementById()

我不知道如何获取表格的元素,因为它们没有我可以使用的 ID 或标记名。正如您在源代码中的这个 sn-p 中看到的那样

                              </span>
                                           </div>
                                       </th>
                                                                                                                                                                                        </tr>
                            </thead>
                            <tbody>
                                                
                                                                                         
                                                                                                                                                                                    <tr>
                             
         <td>18/03/2019</td>
      
         <td><span class="number">20,05</sapn>&nbsp;<span class="symbol"></span></td>
      
         <td><span class="number">2,250</sapn>&nbsp;<span class="symbol">%</span></td>
      
         <td>13/02/2019</td>
      
    
                             </tr>
                        
                                             

这个 sn-p 显示了我要提取的表的第一行。

【问题讨论】:

  • 您的问题很难理解它目前的表述方式。请尝试以更清晰的方式解释您的问题,以便我们为您提供帮助。另外,请确保您的代码 sn-p 完整且格式正确。
  • 请包含您的代码。
  • 注意。感谢您的发言。希望问题更清楚

标签: html excel vba internet-explorer web-scraping


【解决方案1】:

你可以避开浏览器,使用xmlhttp获取页面内容,然后通过class选择table元素(没有id可以使用,class是id之后第二快的选择器),然后循环写入行列出表。

Option Explicit
Public Sub GetTable()
    Dim html As MSHTML.HTMLDocument, hTable As Object, ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    Set html = New MSHTML.HTMLDocument                  '<  VBE > Tools > References > Microsoft Scripting Runtime
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "http://www.bkam.ma/Marches/Principaux-indicateurs/Marche-obligataire/Marche-des-bons-de-tresor/Marche-secondaire/Taux-de-reference-des-bons-du-tresor?date=13%2F02%2F2019&block=e1d6b9bbf87f86f8ba53e8518e882982#address-c3367fcefc5f524397748201aee5dab8-e1d6b9bbf87f86f8ba53e8518e882982", False
        .send
        html.body.innerHTML = .responseText
    End With
    Set hTable = html.querySelector(".dynamic_contents_ref_12")
    Dim td As Object, tr As Object, th As Object, r As Long, c As Long
    For Each tr In hTable.getElementsByTagName("tr")
        r = r + 1: c = 1
        For Each th In tr.getElementsByTagName("th")
            ws.Cells(r, c) = th.innerText
            c = c + 1
        Next
        For Each td In tr.getElementsByTagName("td")
            ws.Cells(r, c) = td.innerText
            c = c + 1
        Next
    Next
End Sub

【讨论】:

    【解决方案2】:

    首先可以根据类属性找到表

    Set HTMLTable = appIE.document.getElementsByClassName("dynamic_contents_ref_12")(0)
    

    这将获取类名为 dynamic_contents_ref_12 的 HTML 元素数组并返回其第一个元素。

    然后,您可以使用 `.Children` 属性“抓取”表格

    这将使您获得第一行:

    Set TBody = HTMLTable.Children(1) 'The <tbody> tag is the second child
    Set Row1 = TBody.Children(0)      'The first <tr> inside the <tbody> tag
    

    对于每一行,在括号中放置一个不同的索引。

    现在Row1 中的 HTML 看起来像

    <tr>
    
      <td>
        18/03/2019
      </td>
    
      <td>
        <span class="number">
          20,05&nbsp;
          <span class="symbol"></span>
        </span>
      </td>
    
      <td>
        <span class="number">
          2,250&nbsp;
          <span class="symbol">%</span>
        </span>
      </td>
    
      <td>
        13/02/2019
      </td>
    
    </tr>
    

    (每个&lt;td&gt; 是行中的一个单元格。)

    要获取单元格内的文本,我们可以使用.innerText 方法,该方法返回一个字符串:

    CellA1 = Row1.Children(0).innerText ' = "05/04/2019"
    CellB1 = Row1.Children(1).innerText ' = "43,85 "
    

    把它们放在一起

    使用For Each 循环,我们可以从 HTML 表格中获取所有单元格并将它们复制到工作表中 - 假设您要从单元格 A1 开始。

    'Table Headers
    ActiveSheet.Range("A1").Value = "Date d'échéance"
    ActiveSheet.Range("B1").Value = "Transaction"
    ActiveSheet.Range("C1").Value = "Taux moyen pondéré"
    ActiveSheet.Range("D1").Value = "Date de la valeur"
    
    Set HTMLTable = appIE.document.getElementsByClassName("dynamic_contents_ref_12")(0)
    Set TBody = HTMLTable.Children(1)
    RowIndex = 2
    For Each Row in TBody.Children
      ActiveSheet.Cells(RowIndex, 1).Value = Row.Children(0).innerText
      ActiveSheet.Cells(RowIndex, 2).Value = Row.Children(1).innerText
      ActiveSheet.Cells(RowIndex, 3).Value = Row.Children(2).innerText
      ActiveSheet.Cells(RowIndex, 4).Value = Row.Children(3).innerText
      RowIndex = RowIndex + 1
    Next
    

    【讨论】:

      猜你喜欢
      • 2021-10-02
      • 2018-11-21
      • 2015-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-01
      相关资源
      最近更新 更多