vba - 使用 VBA excel 多个类名从网站提取数据

标签 vba excel excel-2010 getelementsbyclassname

我知道这个问题已经被问过很多次了,但还没有看到循环遍历 div 并查找具有相同类名的标签的明确答案。

我的第一个问题:

如果我有这样的东西:

<div id="carousel">
   <div id="images">

       <div class="imageElement">
          <img src="img/image1.jpg">
       </div>

       <div class="imageElement">
          <img src="img/image2.jpg">
       </div>

       <div class="imageElement">
           <img src="img/image3.jpg">
       </div>

   </div>

</div>

所以我想获取 div“images”中的所有 img Src 以及 imageElement 类名中的其他内容,并将它们复制到 Excel 中的某些单元格。

第二个问题: 我见过两种使用 VBA 提取 Web 内容的方法,一种使用 IE,另一种使用浏览器以外的代码。

Private Sub pullData_Click()

    Dim x As Long, y As Long
    Dim htm As Object

    Set htm = CreateObject("htmlFile")

    With CreateObject("msxml2.xmlhttp")
        .Open "GET", "http://website.html", False
        .send
        htm.body.innerHTML = .responsetext
    End With

End Sub

第二种方式:

Set ie = New InternetExplorer
    With ie
        .navigate "http://eoddata.com/stockquote/NASDAQ/AAPL.htm"
        .Visible = False
        While .Busy Or .readyState <> READYSTATE_COMPLETE
           DoEvents
        Wend
        Set objHTML = .document
        DoEvents
    End With
    Set elementONE = objHTML.getElementsByTagName("TD")
    For i = 1 To elementONE.Length
        elementTWO = elementONE.Item(i).innerText           
        If elementTWO = "08/10/12" Then
            MsgBox (elementONE.Item(i + 1).innerText)
            Exit For
        End If
    Next i
    DoEvents
    ie.Quit
    DoEvents
    Set ie = Nothing

哪一个更好,为什么?

如果您能帮助我,我将不胜感激。

提前谢谢您。

最佳答案

第一个选项通常更可取,因为它比第二个方法快得多,它直接向 Web 服务器发送请求并返回响应。这比自动化 Internet Explorer(第二个选项)要高效得多;自动化 IE 非常慢,因为您实际上只是浏览网站 - 它不可避免地会导致更多下载,因为它必须加载页面中的所有资源 - 图像、脚本、CSS 文件等。它还会在页面上运行任何 Javascript - 所有这些通常没有用,您必须等待它完成才能解析页面。

然而,这有点像一把双刃剑 - 虽然速度要慢得多,但如果您不熟悉 html 请求,则自动化 Internet Explorer 比第一种方法要容易得多,特别是当元素是动态生成的或页面有依赖时在 AJAX 上。当您需要访问需要您登录的站点中的数据时,自动化 IE 也更容易,因为它会为您处理相关的 cookie。这并不是说第一种方法不能完成网页抓取,而是说它需要对网页技术和网站架构有更深入的了解。

第一种方法的更好选择是使用不同的对象来处理请求和响应,使用 WinHTTP 库比 MSXML 库提供更多的弹性,并且通常也会自动处理任何 cookie。

对于解析数据,在第一种方法中,您使用了后期绑定(bind)来创建 HTML 对象(html 文件),虽然这减少了对引用的需求,但也减少了功能。例如,当使用后期绑定(bind)时,如果用户安装了 IE9,您将错过添加的功能,特别是在本例中的 getElementsByClass 名称函数。

作为第三种选择(也是我的首选方法):

Dim oHtml       As HTMLDocument
Dim oElement    As Object

Set oHtml = New HTMLDocument


With CreateObject("WINHTTP.WinHTTPRequest.5.1")
    .Open "GET", "http://www.someurl.com", False
    .send
    oHtml.body.innerHTML = .responseText
End With

For Each oElement In oHtml.getElementsByClassName("imageElement")
    Debug.Print oElement.Children(0).src
Next oElement

'IE 8 alternative
'For Each oElement In oHtml.getElementsByTagName("div")
'    If oElement.className = "imageElement" Then
'        Debug.Print oElement.Children(0).src
'    End If
'Next oElement

这将需要对 Microsoft HTML 对象库进行引用设置 - 如果用户没有安装 IE9,则会失败,但这是可以处理的,并且变得越来越不相关

关于vba - 使用 VBA excel 多个类名从网站提取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18709911/

相关文章:

excel - 双击宏添加文本

excel - VBA运行时错误 '9' : Subscript out of range; trying to activate another workbook

sql - Excel VBA - 存储过程 (SQL Server)

php - 上传excel文件到服务器

vba - word和excel中的vba是否使用不同的声明?

excel - For Each - 在没有 for 的情况下编译错误

arrays - 我正在尝试返回 Excel UDF 的值数组。我最终只得到第一个值,没有其他值,为什么?

ms-access - 如何在 VBA 代码中的 ms-access 中执行查询?

VBA 循环突出显示不一致

ms-access - TransferText 导出到 CSV 不起作用,但 TransferSpreadsheet 到 XLSX 起作用