【问题标题】:Web-scraping on intranet在 Intranet 上进行 Web 抓取
【发布时间】:2015-01-09 16:44:31
【问题描述】:

我编写了一个 VBA 代码来从我公司的 Intranet 中抓取数据。

问题:

出现以下错误:

运行时错误“91”:
对象变量或未设置块变量

它发生在:

myPoints = Trim(Doc.getElementsByName("price")(0).getAttribute("value"))

当我调试它并逐行运行时,它可以检索所有值。

输入和输出:

我在 B 列输入多个产品 ID 并在 C 列检索数据:
B 列 = 产品 ID
C 列 = 价格

HTML:

<td id="myPower_val_9" style="visibility: visible;">
    <input type="text" disabled="disabled" value="300" name="price"></input>
</td>

VBA:

Sub Button1_Click()

Dim ie As Object
Dim r As Integer
Dim myPoints As String
Dim Doc As HTMLDocument

Set ie = New InternetExplorerMedium

For r = 2 To Range("B65535").End(xlUp).Row

    With ie
        .Visible = 0

        .navigate "www.example.com/product/" & Cells(r, "B").Value

        Do Until .readyState = 4
            DoEvents
        Loop

    End With

    Set Doc = ie.document

    myPoints = Trim(Doc.getElementsByName("price")(0).getAttribute("value"))
    Cells(r, "C").Value = myPoints

Next r

End Sub

我错过了错误处理程序吗?

【问题讨论】:

  • 您是调试了整个循环还是仅调试了一次迭代?对于单次迭代,网页可能不包含所需的元素。尝试设置 ie.visible=true 并在出现错误时分析网页。
  • @silentsurfer 我循环了整个代码,它只发生在那一行。我在家里尝试了我们雅虎金融(互联网)上的类似代码,它工作正常。我可以添加任何错误处理程序来修复代码吗?

标签: excel vba web-scraping intranet


【解决方案1】:

在访问任何元素之前,您需要等待文档完全呈现并且 DOM 可用。一旦页面连接并开始加载,ie.ReadyState 将更改为 READYSTATE_COMPLETE。您的代码在调试时工作的原因是,在您开始使用调试器的几秒钟内,页面就完成了加载。

With ie
   .Visible = True
   .Navigate "www.example.com/product/" & Cells(r, "B").Value

   Do Until .ReadyState = READYSTATE_COMPLETE
       DoEvents
   Loop
   Do Until .Document.ReadyState = "complete"
       DoEvents
   Loop
End With

我还建议您至少在开发时使 ie 窗口可见。完成功能并进行调试后,您可以使窗口不可见。请记住,如果您在代码完成时忘记关闭不可见的 IE 窗口,您的用户最终会遇到失控的 iexplore.exe 进程。

【讨论】:

  • 我不相信这是答案。提问者的代码已经包含一个循环,等待 ie.readyState 变为等于 4。(在 Internet 控件库中,READYSTATE_COMPLETE 等于 4)
  • 我想你误解了我的回答?可能是我措辞不够仔细,但你需要检查 ie.ReadyState 和 ie.Document.ReadyState。 ie.ReadyState 在文档完全加载之前变为 READYSTATE_COMPLETE。只有当 ie.Document.ReadyState == "complete" 时,DOM 才会完全加载。
【解决方案2】:

如果您只想忽略错误并继续下一次迭代,请使用此修改后的代码:

Sub Button1_Click()

Dim ie As Object
Dim r As Integer
Dim myPoints As String
Dim Doc As HTMLDocument


Set ie = New InternetExplorerMedium


For r = 2 To Range("B65535").End(xlUp).Row

With ie
  .Visible = 0

  .navigate "www.example.com/product/" & Cells(r, "B").Value

   Do Until .readyState = 4
   DoEvents
   Loop

End With


 Set Doc = ie.document


 'Edit:
 myPoints = ""

 On Error Resume Next
 myPoints = Trim(Doc.getElementsByName("price")(0).getAttribute("value"))
 On Error Goto 0

 Cells(r, "C").Value = myPoints

Next r

End Sub

【讨论】:

    【解决方案3】:

    你也可以循环直到元素被设置(也可以添加一个超时子句)

    Dim a As Object
    Do
        DoEvents
        On Error Resume Next 
        Set a = Doc.getElementsByName("price")
        On Error GoTo 0
    Loop While a Is Nothing 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-06
      • 2018-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多