我正在编写一个宏,它将抓取我公司的内部SAP站点以获取供应商信息。由于几个原因,我必须使用VBA这样做。但是,当我试图刮擦页面时,我无法弄清楚为什么我会一直收到这三个错误。这可能与UAC integrity model有关吗?或者我的代码有问题吗?使用http的网页是否可以在Internet Explorer中以不同方式处理?我可以访问任何网页,甚至是其他内部网页,并且可以将每个网页都抓得很好。但是当我试图刮取SAP页面时,我得到了这些错误。错误描述及其发生时间为:
800706B5 - 接口未知(在运行违规代码之前放置断点时发生)
80004005 - 未指定错误(当我没有出现任何错误并让宏运行时发生)
80010108 - 调用的对象已与其客户端断开连接。 (我似乎无法得到这个错误的一致发生,似乎发生在excel中的某些东西如此损坏以至于没有页面将加载并且我必须重新安装excel的时候)
我完全不知道发生了什么。 Integrity页面对我来说没有多大意义,我在此发现的所有研究都谈到了连接数据库和使用ADO和COM引用。但是,我通过Internet Explorer做一切。以下是我的相关代码:
Private Sub runTest_Click()
ie.visible = True
doScrape
End Sub
'The code to run the module
Private Sub doTest()
Dim result As String
result = PageScraper.scrapeSAPPage("<some num>")
End Sub
PageScraper模块
Public Function scrapeSAPPage(num As Long) As String
'Predefined URL that appends num onto end to navigate to specific record in SAP
Dim url As String: url = "<url here>"
Dim ie as InternetExplorer
set ie = CreateObject("internetexplorer.application")
Dim doc as HTMLDocument
ie.navigate url 'Will always sucessfully open page, regardless of SAP or other
'pauses the exection of the code until the webpage has loaded
Do
'Will always fail on next line when attempting SAP site with error
If Not ie.Busy And ie.ReadyState = 4 Then
Application.Wait (Now + TimeValue("00:00:01"))
If Not ie.Busy And ie.ReadyState = 4 Then
Exit Do
End If
End If
DoEvents
Loop
Set doc = ie.document 'After implementation of Tim Williams changes, breaks here
'Scraping code here, not relevant
End Function
我在Windows 7计算机上使用IE9和Excel 2010。您将提供的任何帮助或见解将不胜感激。谢谢。
答案 0 :(得分:3)
我经常进行这种类型的抓取,并且发现很难使IE自动化100%可靠地运行,并且出现了您所发现的错误。由于它们通常是计时问题,因此调试非常令人沮丧,因为它们在您单步执行时不会出现,仅在实时运行期间为了最大限度地减少错误,我执行以下操作:
引入更多延迟; ie.busy和ie.ReadyState不一定在ie.navigate之后立即给出有效答案,因此在ie.navigate之后引入一个短暂的延迟。对于我正常加载1到2秒的东西,但是超过500毫秒的东西似乎都能正常工作。
在转到目标网址之前,先通过ie.navigate“about:blank”确保IE处于干净状态。
之后你应该有一个有效的IE对象,你必须看看它,看看你有什么内部。一般来说,我避免尝试访问整个ie.document,而是使用IE.document.all.tags(“x”),其中'x'是我正在寻找的合适的东西,如td或a。
然而,经过所有这些改进,虽然他们提高了我的成功率,但我仍然有随机的错误。
我真正的解决方案是放弃IE,而是使用xmlhttp完成我的工作。
如果您使用文档上的文本操作解析数据,那么交换将是一个明智的选择。 xmlhttp对象更可靠。你只需要“responsetext”来访问文档的整个html。
以下是我现在在生产中用于抓取的简化版本,它非常可靠,可以在一夜之间运行,无错误地生成数百万行。
Public Sub Main()
Dim obj As MSXML2.ServerXMLHTTP
Dim strData As String
Dim errCount As Integer
' create an xmlhttp object - you will need to reference to the MS XML HTTP library, any version will do
' but I'm using Microsoft XML, v6.0 (c:\windows\system32\msxml6.dll)
Set obj = New MSXML2.ServerXMLHTTP
' Get the url - I set the last param to Async=true so that it returns right away then lets me wait in
' code rather than trust it, but on an internal network "false" might be better for you.
obj.Open "GET", "http://www.google.com", True
obj.send ' this line actually does the HTTP GET
' Wait for a completion up to 10 seconds
errCount = 0
While obj.readyState < 4 And errCount < 10
DoEvents
obj.waitForResponse 1 ' this is an up-to-one-second delay
errCount = errCount + 1
Wend
If obj.readyState = 4 Then ' I do these on two
If obj.Status = 200 Then ' different lines to avoid certain error cases
strData = obj.responseText
End If
End If
obj.abort ' in real code I use some on error resume next, so at this point it is possible I have a failed
' get and so best to abort it before I try again
Debug.Print strData
End Sub
希望有所帮助。