【问题标题】:web scraping with vba using XMLHTTP使用 XMLHTTP 使用 vba 进行 Web 抓取
【发布时间】:2014-02-07 23:37:42
【问题描述】:

我想从网页http://www.eex.com/en/market-data/power/derivatives-market/phelix-futures获取一些数据。

如果我使用旧的 InternetExplorer 对象(下面的代码),我可以浏览 HTML 文档。但我想使用XMLHTTP 对象(第二个代码)。

Sub IEZagon() 
     'we define the essential variables
    Dim ie As Object 
    Dim TDelement, TDelements 
    Dim AnhorLink, AnhorLinks 

     'add the "Microsoft Internet Controls" reference in your VBA Project indirectly
    Set ie = CreateObject("InternetExplorer.Application") 
    With ie 
        .Visible = True 
        .navigate ("[URL]http://www.eex.com/en/market-data/power/derivatives-market/phelix-futures[/URL]") 
        While ie.ReadyState <> 4 
            DoEvents 
        Wend 
        Set AnhorLinks = .document.getElementsbytagname("a") 
        Set TDelements = .document.getElementsbytagname("td") 
        For Each AnhorLink In AnhorLinks 
            Debug.Print AnhorLink.innertext 
        Next 
        For Each TDelement In TDelements 
            Debug.Print TDelement.innertext 
        Next 
    End With 
    Set ie = Nothing 
End Sub

使用带有 XMLHTTP 对象的代码:

Sub FuturesScrap(ByVal URL As String) 
    Dim XMLHttpRequest As XMLHTTP 
    Dim HTMLDoc As New HTMLDocument 

    Set XMLHttpRequest = New MSXML2.XMLHTTP 
    XMLHttpRequest.Open "GET", URL, False 
    XMLHttpRequest.send 
    While XMLHttpRequest.readyState <> 4 
        DoEvents 
    Wend 

    Debug.Print XMLHttpRequest.responseText 
    HTMLDoc.body.innerHTML = XMLHttpRequest.responseText 

    With HTMLDoc.body 
        Set AnchorLinks = .getElementsByTagName("a") 
        Set TDelements = .getElementsByTagName("td") 

        For Each AnchorLink In AnchorLinks 
            Debug.Print AnhorLink.innerText 
        Next 

        For Each TDelement In TDelements 
            Debug.Print TDelement.innerText 
        Next 
    End With 
End Sub 

我只得到基本的 HTML:

<html> 
<head> 
<title>Resource Not found</title> 
<link rel= 'stylesheet' type='text/css' href='/blueprint/css/errorpage.css'/>
</head> 
<body> 
<table class="header"> 
<tr> 
<td class="CMTitle CMHFill"><span class="large">Resource Not found</span></td> 
</tr> 
</table> 
<div class="body"> 
<p style="font-weight:bold;">The requested resource does Not exist.</p> 
</div> 
<table class="footer"> 
<tr> 
<td class="CMHFill"> </td> 
</tr> 
</table> 
</body> 
</html>

我想浏览表格和对应的数据... 最后我想从年到月选择不同的时间间隔:

非常感谢任何帮助!谢谢!

【问题讨论】:

  • 看起来您请求的 URL 不正确...
  • 我正在整理正确的网址:
  • 见@brettdj 的回复HERE
  • 我昨天读了这篇文章,但我没有找到关于使用 XMLHTTP 对象抓取页面的答案。 Www 我正在使用 javascript 来显示所有财务数据,所以问题在于 readystate 和使用 XMLHTTP 对象的权利。我没有使用旧的 InternetExplorer 的问题。但它很慢而且不舒服......

标签: html vba excel web-scraping


【解决方案1】:

我可以确认我在运行您的代码时获得了与您相同的 HTML(带有或不带有 url 标签)。我发现了一个有用的帖子here。我已经使用那里找到的方法修改了您的代码,现在它似乎已经下载了正确的信息。

Sub test()
    Call FuturesScrap1("http://www.eex.com/en/market-data/power/derivatives-market/phelix-futures")
End Sub

我包含了调用子,因为 url 标记似乎会导致 MSXML 请求出错。

Sub FuturesScrap1(ByVal URL As String)
    Dim HTMLDoc As New HTMLDocument
    Dim oHttp As MSXML2.XMLHTTP
    Dim sHTML As String
    Dim AnchorLinks As Object
    Dim TDelements As Object
    Dim TDelement As Object
    Dim AnchorLink As Object

    On Error Resume Next
    Set oHttp = New MSXML2.XMLHTTP
    If Err.Number <> 0 Then
        Set oHttp = CreateObject("MSXML.XMLHTTPRequest")
        MsgBox "Error 0 has occured while creating a MSXML.XMLHTTPRequest object"
    End If
    On Error GoTo 0
    If oHttp Is Nothing Then
        MsgBox "For some reason I wasn't able to make a MSXML2.XMLHTTP object"
        Exit Sub
    End If

    'Open the URL in browser object
    oHttp.Open "GET", URL, False
    oHttp.send
    sHTML = oHttp.responseText

    Debug.Print oHttp.responseText

    HTMLDoc.body.innerHTML = oHttp.responseText

    With HTMLDoc.body
        Set AnchorLinks = .getElementsByTagName("a")
        Set TDelements = .getElementsByTagName("td")

        For Each AnchorLink In AnchorLinks
            Debug.Print AnchorLink.innerText
        Next

        For Each TDelement In TDelements
            Debug.Print TDelement.innerText
        Next
    End With

End Sub

编辑以下评论:

我无法使用 MSXML2 对象找到表格元素,源代码似乎不包含它们。在 firebug 中存在 td 标签,所以我认为该表是由 JavaScript 代码生成的。我不知道 MSXML2 是否可以运行 JavaScript,所以我修改了 sub 以使用 Internet Explorer,它不是快速代码,但它确实找到了 td 元素并允许单击选项卡。我发现 td 元素可能需要一些时间才能变得可用(大概 IE 必须运行 JavaScript)所以我已经采取了几个步骤,xl 在下载数据之前等待。

我已经添加了一些代码,将 td 元素的内容下载到活动工作表中,如果在包含有用数据的工作簿中运行它,请小心。

Sub FuturesScrap3(ByVal URL As String)

    Dim HTMLDoc As New HTMLDocument
    Dim AnchorLinks As Object
    Dim tdElements As Object
    Dim tdElement As Object
    Dim AnchorLink As Object
    Dim lRow As Long
    Dim oElement As Object

    Dim oIE As InternetExplorer

    Set oIE = New InternetExplorer

    oIE.navigate URL
    oIE.Visible = True

    Do Until (oIE.readyState = 4 And Not oIE.Busy)
        DoEvents
    Loop

    'Wait for Javascript to run
    Application.Wait (Now + TimeValue("0:01:00"))

    HTMLDoc.body.innerHTML = oIE.document.body.innerHTML

    With HTMLDoc.body
        Set AnchorLinks = .getElementsByTagName("a")
        Set tdElements = .getElementsByTagName("td") '

        For Each AnchorLink In AnchorLinks
            Debug.Print AnchorLink.innerText
        Next AnchorLink

    End With

    lRow = 1
    For Each tdElement In tdElements
        Debug.Print tdElement.innerText
        Cells(lRow, 1).Value = tdElement.innerText
        lRow = lRow + 1
    Next

    'Clicking the Month tab
    For Each oElement In oIE.document.all
        If Trim(oElement.innerText) = "Month" Then
            oElement.Focus
            oElement.Click
        End If
    Next oElement

    Do Until (oIE.readyState = 4 And Not oIE.Busy)
        DoEvents
    Loop

    'Wait for Javascript to run
    Application.Wait (Now + TimeValue("0:01:00"))

    HTMLDoc.body.innerHTML = oIE.document.body.innerHTML

    With HTMLDoc.body
        Set AnchorLinks = .getElementsByTagName("a")
        Set tdElements = .getElementsByTagName("td") '

        For Each AnchorLink In AnchorLinks
            Debug.Print AnchorLink.innerText
        Next AnchorLink
    End With

    lRow = 1
    For Each tdElement In tdElements
        Debug.Print tdElement.innerText
        Cells(lRow, 2).Value = tdElement.innerText
        lRow = lRow + 1
    Next tdElement

End sub

【讨论】:

  • 我上周六做了同样的代码。但是我在这个网页上仍然有问题。使用您和我的代码,我无法列出名称为 Year through Day 的 6 个按钮(锚点)。如果我想根据时间窗口(年、季度等)浏览不同的表格,我需要点击任何一个按钮。但这不是最后一个问题,在我们的代码中我们不能用代码列出表格数据: [code] For Each TDelement In TDelements Debug.Print TDelement.innerText Next [\code]
  • @Figlio 我已经修改了答案以获取 TD 元素并允许更改表格,但它使用 Internet Explorer,而不是 MSXML2,这可能是由于 JavaScript 所必需的。
  • 谢谢。与 IE 对象一起工作。我知道,我制作了与您制作的代码相同的代码。我有同样的问题需要 Application.wait 方法。如果是这样并且不使用 XMLHTTP,我将留在 IE 上。再次感谢!
猜你喜欢
  • 2018-10-23
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 2018-12-10
  • 2019-03-15
  • 2019-04-03
  • 2017-11-04
相关资源
最近更新 更多