在Excel VBA中,检查网页是否已完全加载的方法是什么?

时间:2017-11-01 20:02:31

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

要暂停代码直到网页完全加载,我几乎一直都在使用以下方法取得巨大成功。

Do While objIE.Busy = True Or objIE.readyState <> 4: DoEvents: Loop

但偶尔会在方法确定页面已完全加载后看到文本内容加载,因此不会提取内容。

但是,如果我通过F8单步执行代码,则每次都会提取内容。这是我可以反复按F8键的速度。

那么在代码继续提取数据之前,如何检查以确保页面及其所有内容已完全加载?

在这两种情况下,IE都是无形的运行。但是,我已经尝试使用IE浏览器,并且在我正在使用的页面上的这个特定位置实际上有内容。

这是在Excel 2016中使用VBA脚本完成的。具体内容请求的写法如下:

 'get item name from page and write it to the first cell on the first empty row available
 Set itemName = objIE.document.querySelector(".the-item-name")
 Worksheets("Results").Range("A1048576").End(xlUp).Offset(1, 0).Value = itemName.innerText

我已阅读Excel VBA: Wait for JavaScript execution in Internet Explorer,因为我认为可能会在文档加载后添加值,以防止任何人抓取数据。但是,我似乎无法识别可能正在执行此操作的任何脚本。并不意味着它不存在。我还是看不到它。

有此问题的网页的具体示例是网址

https://www.homedepot.ca/en/home/p.dry-cloth-refills-32---count.1000660019.html

最初product-total-price div元素包含破折号( - ),在加载价格之前,这就是请求将返回的内容:- / each而不是$11.29 / each

我有一个解决方法,但它不像我希望的那样高效或简洁。我测试返回的字符串是否存在破折号。如果它在那里,循环并再次检查它,否则捕获它并将其插入工作表。

setPriceUM:
    Set hdPriceUM = objIE.document.querySelector(".product-total-price").innerTe‌​‌​xt
    hdPriceUMString = hdPriceUM.innerText
    stringTest = InStr(hdPriceUMString, "-")
    If stringTest = True Then
        GoTo setPriceUM
    Else
        Debug.Print hdPriceUMString
    End If

感谢您花时间阅读并考虑它。

1 个答案:

答案 0 :(得分:2)

网页的功能非常不同,因此没有适合所有网页的解决方案。

关于您的示例,您的解决方法是一个有效的解决方案,代码可能如下:

Sub TestIE()

    Dim q

    With CreateObject("InternetExplorer.Application")
        .Visible = True
        .Navigate "https://www.homedepot.ca/en/home/p.dry-cloth-refills-32---count.1000660019.html"
        ' Wait IE
        Do While .readyState < 4 Or .Busy
            DoEvents
        Loop
        ' Wait document
        Do While .document.readyState <> "complete"
            DoEvents
        Loop
        ' Wait element
        Do
            q = .document.querySelector(".product-total-price").innerText
            If Left(q, 1) <> "-" Then Exit Do
            DoEvents
        Loop
        .Quit
    End With
    Debug.Print q

End Sub

无论如何,您需要使用浏览器开发人员工具(F12)查看网页加载过程,XHR和DOM修改。通过这种方式,您可能会发现众多XHR中的一个以JSON格式返回价格。它在浏览器开发者工具的网络选项卡上登录,正好在页面加载时出现价格。 XHR是由一个加载的JS创建的,特别是在页面加载事件之后。试试这个URL(我刚刚从网络标签中复制了它):

https://www.homedepot.ca/homedepotcacommercewebservices/v2/homedepotca/products/1000660019/localized/9999?catalogVersion=Online&lang=en

因此,您可以通过拆分来重现该XHR并提取价格:

Sub TestXHR()

    Dim q

    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "https://www.homedepot.ca/homedepotcacommercewebservices/v2/homedepotca/products/1000660019/localized/9999?catalogVersion=Online&lang=en", False
        .Send
        q = .ResponseText
    End With
    q = Replace(q, " : ", ":")
    q = Split(q, """displayPrice""", 2)(1)
    q = Split(q, """formattedValue"":""", 2)(1)
    q = Split(q, """", 2)(0)
    Debug.Print q

End Sub

但同样,没有常见的情况。

您也可以使用JSON解析器,查看some examples