我理解已经回答了类似的问题,但我不确定我是否无法理解如何从其他人的答案中找到解决方案,或者我需要获取信息的网站很复杂。所以,请帮助我。
我想从Delphi for PN#13511996获取描述字段,值应为“3 Way Grey GT 150密封母连接器组件,最大电流15安培”。有人可以帮我检查网站,让我知道如何获取说明吗?
Sub GetData()
'Added Microsoft HTML Object library to reff
'Added Microsoft XML, v6.0 to reff
Dim xhr As MSXML2.XMLHTTP60
Dim doc As MSHTML.HTMLDocument
Dim desc As String
Set xhr = New MSXML2.XMLHTTP60
With xhr
.Open "GET", "http://ecat.delphi.com/feature?search=13511996", False
.send
If .ReadyState = 4 And .Status = 200 Then
Set doc = New MSHTML.HTMLDocument
doc.body.innerHTML = .responseText
End If
End With
With doc
desc = .getElementsByClassName("ProductDetail.Description").Item(0).innerText
End With
Debug.Print desc
End Sub
答案 0 :(得分:0)
这是因为您使用GET
中的XMLHTTP
来请求原始HTML。如果您尝试Debug.Print doc.body.innerHTML
,您会看到该表尚未生成,并且您要查找的文本根本不存在。
为了能够运行项目" 13511996"的查询,您需要一个真正的浏览器。只有这样,您才能生成表并获取DOM文档对象。请尝试以下代码:
Sub GetData()
Dim aIE As InternetExplorer
Dim desc As IHTMLElement
Set aIE = New InternetExplorer
With aIE
.navigate "http://ecat.delphi.com/feature?search=13511996"
.Visible = True '----> set it to false if you dont want to see the browser
End With
Do While (aIE.Busy Or aIE.ReadyState <> READYSTATE_COMPLETE)
DoEvents
Loop
Set desc = aIE.document.getElementsByClassName("DetailAttributes")(0)
'Debug.Print desc.innerText '---> prints the whole table data
Debug.Print Split(desc.innerText, vbLf)(3) '----> prints the forth data in table
Set aIE = Nothing
Set desc = Nothing
End Sub
此外,如果您计划自动执行此代码以在多个查询的循环中运行,您可能希望使用:
Set desc = Nothing
For i = 1 To 100
On Error Resume Next
Set desc = aIE.document.getElementsByClassName("DetailAttributes")(0)
If Err.Number = 91 Then
GoTo Skip
End If
Exit For
Skip:
Application.Wait (Now() + TimeValue("00:00:001"))
Next i
而不是:
Set desc = aIE.document.getElementsByClassName("DetailAttributes")(0)
这是因为有时网页在完全生成其内容之前就已准备就绪。这会导致代码退出do loop
并继续执行设置desc
对象的下一个语句。您在设置时不会收到错误,因为代码将使用以前的DOM文档对象,并将输出您之前查询的结果,这是一个错误。没有任何错误,你的代码将循环运行直到结束,你手中将有一个完全扭曲的输出,这是浪费时间。
要解决此问题,您应事先将对象设置为nothing
,并捕获错误并等待页面加载到for loop
。
最后但同样重要的是,如果构建您正在解析的网页的人知道他们正在做什么,他们可能会保护它免受来自同一来源的多个查询(很可能来自多个来源),这可能会导致他们的服务器崩溃,如果他们不这样做。此保护将在有限的时间内作为有限数量的查询反映给您。换句话说,例如在5分钟内发出100次请求后,网页将不会响应某段时间(例如2分钟)。
要解决此问题,您应限制请求数并等待所需时间。假设您使用i
变量递增循环。然后你需要在循环结束时插入它:
If i Mod 100 = 0 Then
Application.Wait (Now() + TimeValue("00:02:00"))
End If
我希望上面提到的解决方案可以解决每个人过去和未来的问题,这需要我花费相当多的时间来解决。