【问题标题】:Web Scraper - Run Time Error 13 on .document.getElementById("")Web Scraper - .document.getElementById("") 上的运行时错误 13
【发布时间】:2018-03-19 19:28:32
【问题描述】:

第一个网页抓取项目!

我一直在从这里复制各种网络抓取代码,但无法绕过

运行时错误 13:类型不匹配

.document.getElementById("") 行上,我用来为要单击的超链接设置变量。我认为它应该被视为我成功编码的登录按钮。我不确定我是否缺少我应该使用的库,因为几乎所有其他帖子都有与我遇到的不同的问题和解决方案。我在这里做错了什么?

我正在使用 IE11 和 Excel 2010。我开始添加我认为可能会提供解决方案的库。我激活的库如下:

  • Visual Basic 应用程序
  • Microsoft Excel 14.0 对象库
  • OLE 自动化
  • Microsoft Office 14.0 对象库
  • Microsoft HTML 对象库
  • Microsoft Internet 控件
  • 微软 XML,v6.0
  • Microsoft Shell 控件和自动化

这里是代码和 HTML DOM sn-p:

Sub IEScrape()
  'we define the essential variables
 Dim ie As Object
 Dim pwd, username
 Dim button
 Dim MemAss

'add the "Microsoft Internet Controls" reference in your VBA Project indirectly
 Set ie = New InternetExplorerMedium
 With ie
     .Visible = True
     .navigate ("internalwebsite.com")
     While ie.readyState <> 4
         DoEvents
     Wend

     Set username = .document.getElementById("userid") 'id of the username control (HTML Control)
     Set pwd = .document.getElementById("password") 'id of the password control (HTML Control)
     Set button = .document.getElementById("loginbtn") 'id of the button control (HTML Control)
     username.Value = "username"
     pwd.Value = "password"
     button.Click
     While ie.readyState <> 4
         DoEvents
     Wend

    'Run time error 13: Type mismatch on next line!!!
    Set MemAss = .document.getElementById("Menu:membershipassociation") 'id of the link (HTML Control)
    MemAss.Click
    While ie.readyState <> 4
         DoEvents
    Wend

 End With



 Set ie = Nothing
 End Sub

【问题讨论】:

  • 尝试只在同一行附加.Click,而不设置变量(在这种情况下为MemAss)。 .document.getElementById("Menu:membershipassociation").Click.
  • @NicholasKemp 我收到运行时错误 424:需要对象
  • 您是否使用所有这些参考资料?
  • @ashleedawg 绝对是其中一些。我会说最后两个,也许我不是 OLE 自动化,但不知道如何检查。我刚开始随意添加它们,看看它们是否有帮助。
  • 我认为您可能没有在模块的最顶部使用Microsoft HTML Object Library, Miicrosoft XML, v6.0, Microsoft Shell Controls And Automation. Also, make sure you have Option Explicit`(总是)。这些东西不一定会帮助您找到 this 错误,但会有助于防止其他错误。对于这个问题,也许您可​​以使用getElementsByClassName 来代替课程。您确定您在 HTML 的正确部分吗? (document.innerhtml 的值是否与您期望的一样?)

标签: html vba excel


【解决方案1】:

正如您所提到的,将代码暂停 5 秒可以让代码正常运行,我假设 HTML 加载 AJAX 请求或编辑 DOM 的 JavaScript 异步发生了一些事情。

这意味着一旦 HTML 已加载 (Readystate = 4),JavaScript 可能仍在运行,或者我们可能仍在等待 AJAX 响应。

按照您的方式等待代码将允许 Internet Explorer 在 VBA 获取引用之前完成其所有任务。虽然缺点是您正在等待任意时间,并且在此时间间隔内不会加载更改。

为了构建更强大的控件(如果需要),我建议在 VBA 之外加载网页并使用浏览器调试器菜单在任何 DOM 更改上添加断点,然后等到您看到 "Menu:membershipassociation" 何时出现定义。然后,我会注意调用此过程的过程,并查看如何将脚本绑定到其中。理想的结果是,如果此数据在加载时存储在页面中,或者存储在您可以直接访问 VBA 的其他位置。

尽管过去我遇到了这个障碍,但我已经使用迭代器定期进行一次尝试,这可能能够加快您在本节中的代码速度。我还喜欢在我不能 100% 确定是否立即可用的任何 DOM 上使用这些迭代器。基本上只是尝试每秒或 0.5 秒加载一次代码,直到它加载完毕。

如果您在浏览器中调试网页时我会提出另一个建议,如果在加载页面时数据可用,那么问题可能是由于您试图立即调用 click 方法。您可以尝试使用IE_DocumentComplete 事件来表示这是可用的。 Here 发布了一个示例,可能会有所帮助。

如果您能够在页面加载时向我们提供您在调试页面时发现的最新信息,我们可以为您指明解决问题的更好方向。

【讨论】:

    【解决方案2】:

    我不知道为什么会这样,但我暂停了这个过程 5 秒钟,突然间,它识别出了.Document.getElementById("Menu:membershipassociation").Click。如果有人对我的过程有任何批评,您可以使用更好的代码发布答案,我会将其标记为正确。

    代码如下:

    Option Explicit
    
    Sub IEScrape()
      'we define the essential variables
     Dim ie As Object
     Dim pwd, username
     Dim button
     Dim MemAss
    
    'add the "Microsoft Internet Controls" reference in your VBA Project indirectly
     Set ie = New InternetExplorerMedium
     With ie
         .Visible = True
         .Navigate ("internalwebsite.com")
         While ie.ReadyState <> 4
             DoEvents
         Wend
    
         Set username = .Document.getElementById("userid") 'id of the username control (HTML Control)
         Set pwd = .Document.getElementById("password") 'id of the password control (HTML Control)
         Set button = .Document.getElementById("loginbtn") 'id of the button control (HTML Control)
         username.Value = "username"
         pwd.Value = "password"
         button.Click
         While ie.ReadyState <> 4
             DoEvents
         Wend
    
        Application.Wait (Now + TimeValue("0:00:05"))
        .Document.getElementById("Menu:membershipassociation").Click
    
        While ie.ReadyState <> 4
             DoEvents
        Wend
    
     End With
    
    
    
     Set ie = Nothing
     End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-10
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      相关资源
      最近更新 更多