要暂停代码直到网页完全加载,我几乎一直都在使用以下方法取得巨大成功。
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").innerText
hdPriceUMString = hdPriceUM.innerText
stringTest = InStr(hdPriceUMString, "-")
If stringTest = True Then
GoTo setPriceUM
Else
Debug.Print hdPriceUMString
End If
感谢您花时间阅读并考虑它。
答案 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(我刚刚从网络标签中复制了它):
因此,您可以通过拆分来重现该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。