Web Scraper - .document.getElementById上的运行时错误13("")

时间:2018-03-19 19:28:33

标签: html vba excel-vba excel

第一个网络抓取项目!

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

  

运行时错误13:输入不匹配

我在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 行上的

用于为我想要点击的超链接设置变量。我认为它应该被视为我成功编码的登录按钮。我不确定我是否错过了我应该使用的库,因为几乎所有其他帖子都有不同的问题和解决方案,而不是我遇到的问题。我在这里做错了什么?

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

  • Visual Basic For Applications
  • Microsoft Excel 14.0对象库
  • OLE自动化
  • Microsoft Office 14.0对象库
  • Microsoft HTML对象库
  • Microsoft Internet Controls
  • Microsoft XML,v6.0
  • Microsoft Shell控件和自动化

以下是代码和HTML DOM代码段:

    mListview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
               Intent intentToYoklamaAl = new Intent(CurrentActivity.this, SecondActivity.class);
         //   intentToYoklamaAl.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intentToYoklamaAl);
           // overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
          //  finish();
        }
    });

td element info

2 个答案:

答案 0 :(得分:2)

正如你所提到的,暂停代码5秒允许代码运行我会假设有一些异步发生在加载AJAX请求或JavaScript编辑DOM的HTML上。

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

等待代码可以让Internet Explorer在VBA获取引用之前完成所有任务。虽然缺点是您正在等待任意数量的时间并且有一个更改,但它不会在此时间间隔内加载。

为了构建一个更健壮的控件(如果需要),我建议在VBA之外加载网页,并使用浏览器调试器菜单在任何DOM更改上添加断点,然后等到你能看到{{1}的时候被定义。然后我会关注这个叫做这个的过程,看看你如何将你的脚本绑定。理想的结果是,如果这些数据在加载时存储在页面中,或者在另一个位置,你可以直接到达你的VBA。

虽然过去我遇到过这个障碍时,我已经使用了一个迭代器来定期进行,这可能会加快你在这一部分的代码。我也喜欢在任何我不是100%确定可立即使用的DOM上使用这些迭代器。基本上只是尝试每秒或0.5秒加载代码,直到它加载。

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

如果您能够根据调试页面的内容更新我们,那么我们可以为您提供更好的方向来解决问题。

答案 1 :(得分:0)

我不知道为什么会这样,但我暂停了这个过程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