VBA / VBscripting自动化的Web Scraping循环与IElogin

我一直在试图编写一个脚本,将网站在渲染网站上的某个字段/标签。 该网站与Excel中的列列表中的search参数呈现。 Appox 20个项目将会增长。 在研究如何使用vbscript来抓取网页之后,我遇到的问题是如何做20次而不会中断。 这是我的代码。

Excel列

1492565 1528417 1529041 1530688 1492038 1492319 1492972 1508824 1513351 1514724 1514750 1518526 1520627 1520706 1520979 1523367 1523563 

Script:Main sub(从excelinput字段获取用户名/密码,通过特定列上的行设置循环,只有吐出msgbox才能使循环工作,然后输出到另一列

 Sub WebScrapper() 'itg on mainWS start row 6, column 5 'itg status column column 19 'declare variables Dim url As String Dim ITGNUMBER As Long Dim user As String Dim pwd As String 'set variables url = "https://website/itg/web/knta/crt/RequestDetail.jsp?REQUEST_ID=" Set oMainWS = ActiveWorkbook.Worksheets("MainWS") Set oITGStatusWS = ActiveWorkbook.Worksheets("ITGStatus") user = "" pwd = "" user = oITGStatusWS.ITGusername.Value pwd = oITGStatusWS.ITGpassword.Value If user = "" Or pwd = "" Then MsgBox ("You must enter username/password before continuing") Exit Sub End If 'log in Set objIE = FirstIEConnect(user, pwd) 'start row is 6 RowCounter = 58 ColumnCounter = 5 ITGStatusColumn = 16 Do Until IsEmpty(oMainWS.Cells(RowCounter, 5).Value) 'get ITG number currentITGNumber = oMainWS.Cells(RowCounter, 5).Value MsgBox (currentITGNumber) 'get remote status currentITGStatus = getITGStatusFunction(objIE.Application, Str(currentITGNumber)) MsgBox (currentITGStatus) 'paste into column 19 'oMainWS.Cells(RowCounter, 19).Value = currentITGStatus 'increment counter RowCounter = RowCounter + 1 currentITGStatus = "" currentITGNumber = "" Loop quitIE (objIE.Application) End Sub 

Sub来退出对象清理,有一个javascript函数来把用户登出。

 Sub quitIE(obj As Object) obj.Navigate ("javascript: closeChildWindowsAndLogout();") obj.Quit End Sub 

从谷歌得到这个子,用来等待IE对象准备就绪。 这实际上在循环中失败了很多。 在做,而IE.Busy:循环。 只是挂起。

 Sub Wait(obj As Object) Do While obj.Busy: Loop Do While obj.readyState <> 4: Loop Application.Wait (Now + TimeValue("0:00:01")) End Sub 

该网站需要login,用户/ pwd是从第一个子。 这个子创buildIE对象,导航到login页面,并将user / pwd插入Document.logon.UserNameDocument.logon.Password 。 最后提交。

 Function FirstIEConnect(user As String, pwd As String) loginURL = "https://website/Logon.jsp" Set IE = CreateObject("InternetExplorer.Application") IE.Visible = False IE.Navigate loginURL Wait (IE.Application) With IE.Document.logon .UserName.Value = user .Password.Value = pwd .submit End With Set FirstIEConnect = IE End Function 

这是实际的网页抓取function。 要求用户从上面loginIE对象。 将numinput到url GET请求中以呈现特定页面。 最后抓取基于ElementID的responseText

 Function getITGStatusFunction(obj, num) On Error Resume Next 'set url and num url = "https://website/RequestDetail.jsp?REQUEST_ID=" & num obj.Navigate url Wait (obj.Application) responseText = obj.Document.getElementByID("DRIVEN_STATUS_ID").innerHTML getStatusFunction = responseText End Function 

再次,问题是,当我试图从不同的子和函数传递IE对象时,我总是收到对象错误。

期望:我希望脚本遍历Excel中包含唯一编号的列信息。 把这些数字逐一join到searchurl中。 一旦页面加载了ElementID(DRIVEN_STATUS_ID) 。 最终将这个值输出到另一列。

Wait (IE)传递IE.Name而不是对象。 要传递对象,请使用IE.Application

蒂姆·威廉姆斯的评论也是正确的,舍弃括号也会导致对象被传递。 所以Wait IE而不是Wait (IE)也将工作。 但是我认为使用Wait IE.Application安全。 显然,你决定。

如果你要更新等待function,它仍然不能解决这个问题,但是在问题出现的地方会更加明显。 Function Wait(IE as object)尝试调用函数时失败,说明需要一个对象。

这应该是显而易见的,但是不要通过IE ,在所有情况下IE.Application传递IE.Application ,除非你真的只想要对象的名字。

顺便说一下, Set variable = IE行很好,因为关键字Set使得它清楚你想要的对象。

只是在黑暗中拍摄,但这听起来像HTML尝试设置值时未完全加载。 尝试使用更长的等待值。 通常3-4秒钟就可以完成。

或者你可以创build一个新的variables,并设置一个循环,直到对象被设置为止:

 Dim obj_testVariable as Object Do Until Not obj_testVariable Is Nothing set obj_testVariable = obj.Document.getElementByID("DRIVEN_STATUS_ID") Loop responseText = obj_testVariable.innerHTML set obj_testVariable = Nothing 

(另)

这是我的IEWaitfunction:

 Dim IE As Object Function IEWait(t As Long) Do While IE.Busy Application.Wait DateAdd("s", t, Now) Loop End Function 

你可以在你的子程序中使用它:

 IEWait (1) Do Until IE.readyState = READYSTATE_COMPLETE: DoEvents: Loop 

提交内容时,只能使用第一行,而在加载新页面时使用两行。 只是玩耍,这将需要一些时间。 祝你好运。