使用VBA爬取密码保护网站数据时遇“用户定义类型未定义”错误
解决VBA导入密码保护网站数据的两大问题:类型未定义错误与代码卡顿
我来帮你一步步搞定这个问题,你遇到的两个核心问题其实都有明确的解决路径,咱们一个个来:
一、先解决「User-defined type not defined」错误
这个报错的原因很直接:你没有引用VBA操作IE需要的库,或者可以改用后期绑定来绕开引用问题,两种方案任选:
方案1:添加库引用
- 打开Excel的VBA编辑器(按
Alt+F11) - 点击顶部菜单栏的「工具」→「引用」
- 在弹出的列表里找到「Microsoft Internet Controls」(有些版本显示为
SHDocVw),勾选它之后点击「确定」 - 回到代码里,原来的
Dim ieApp As InternetExplorer就可以正常使用了
方案2:改用后期绑定(更兼容,无需手动引用)
把代码里的Dim ieApp As InternetExplorer改成Dim ieApp As Object,然后创建实例的代码改成:
Set ieApp = CreateObject("InternetExplorer.Application")
这种方式不用手动添加引用,在不同电脑上运行兼容性更好。
二、修改代码处理密码登录与卡顿问题
你原来的代码没处理网站的登录步骤,直接导航到需要权限的页面肯定会卡住,而且IE本身现在很多网站支持不好,咱们调整代码加入登录逻辑:
完整修改后的VBA代码(IE版)
Sub GetPasswordProtectedPortData() Dim ieApp As Object ' 后期绑定,避免引用问题 Dim ieDoc As Object Dim ieTable As Object Dim clip As DataObject Dim usernameBox As Object Dim passwordBox As Object Dim loginBtn As Object ' 创建IE实例,设为Visible=True方便调试(发布时可改False) Set ieApp = CreateObject("InternetExplorer.Application") ieApp.Visible = True ' 先导航到登录页面(注意:需要确认网站实际的登录URL,我这里是示例) ieApp.Navigate "https://www.vesseltracker.com/fr/Account/Login.html" ' 等待页面完全加载(必须加,否则找不到元素) Do While ieApp.Busy Or ieApp.ReadyState <> 4 DoEvents ' 让Excel在等待时响应其他操作 Loop ' 获取页面文档对象 Set ieDoc = ieApp.Document ' 填写用户名和密码(需要替换成页面实际的元素ID/Name,用浏览器F12查看) Set usernameBox = ieDoc.getElementById("username") ' 替换为实际用户名输入框的ID If Not usernameBox Is Nothing Then usernameBox.Value = "你的用户名" ' 换成你的账号 End If Set passwordBox = ieDoc.getElementById("password") ' 替换为实际密码输入框的ID If Not passwordBox Is Nothing Then passwordBox.Value = "你的密码" ' 换成你的密码 End If ' 点击登录按钮(同样替换为实际按钮的ID/选择器) Set loginBtn = ieDoc.getElementById("loginButton") ' 替换为实际登录按钮的ID If Not loginBtn Is Nothing Then loginBtn.Click End If ' 等待登录跳转完成 Do While ieApp.Busy Or ieApp.ReadyState <> 4 DoEvents Loop ' 导航到目标港口数据页面 ieApp.Navigate "https://www.vesseltracker.com/fr/Ports/Home.html" ' 再次等待页面加载 Do While ieApp.Busy Or ieApp.ReadyState <> 4 DoEvents Loop ' 获取目标表格(这里假设第一个表格是你要的,实际用F12确认表格的位置或ID) Set ieTable = ieDoc.getElementsByTagName("table")(0) ' 把表格内容复制到剪贴板再粘贴到Excel Set clip = New DataObject clip.SetText ieTable.outerHTML clip.PutInClipboard ThisWorkbook.Sheets("Sheet1").Range("A1").PasteSpecial ' 清理资源,关闭IE ieApp.Quit Set ieApp = Nothing Set ieDoc = Nothing Set ieTable = Nothing Set clip = Nothing End Sub
关键注意事项
- 你需要用浏览器的开发者工具(按
F12)查看目标网站的登录页面元素,把代码里的username、password、loginButton换成页面实际的元素ID或Name - 如果IE还是卡顿,大概率是网站已经停止对IE的支持,建议改用下面的现代方案
三、更稳定的替代方案:用Selenium Basic操作Edge/Chrome
IE已经被微软淘汰,很多网站不再兼容,用Selenium Basic配合现代浏览器(Edge/Chrome)会更稳定:
- 先安装Selenium Basic,并下载对应浏览器的驱动(比如EdgeDriver)
- 在VBA编辑器的「工具」→「引用」里添加「Selenium Type Library」
- 示例代码:
Sub GetPortDataWithSelenium() Dim driver As New EdgeDriver ' 换成ChromeDriver如果你用Chrome Dim usernameBox As WebElement Dim passwordBox As WebElement Dim loginBtn As WebElement Dim targetTable As WebElement ' 启动浏览器 driver.Start "edge" ' 导航到登录页 driver.Get "https://www.vesseltracker.com/fr/Account/Login.html" ' 填写登录信息 Set usernameBox = driver.FindElementById("username") usernameBox.SendKeys "你的用户名" Set passwordBox = driver.FindElementById("password") passwordBox.SendKeys "你的密码" ' 点击登录 Set loginBtn = driver.FindElementById("loginButton") loginBtn.Click ' 等待跳转后导航到目标页 driver.Wait 5000 ' 等待5秒,可根据实际加载速度调整 driver.Get "https://www.vesseltracker.com/fr/Ports/Home.html" ' 复制表格到Excel Set targetTable = driver.FindElementByTagName("table") targetTable.Copy ThisWorkbook.Sheets("Sheet1").Range("A1").PasteSpecial ' 关闭浏览器 driver.Quit Set driver = Nothing End Sub
内容的提问来源于stack exchange,提问作者data maths




