Vba 项目搜索宏
我有一个Excel宏,可以从网站上搜索商品编号,并从网页上删除一些特定信息,如可用性、价格、页面URL。但在抓取了一些页面后,它给了我以下错误: 运行时错误91,未设置对象变量或带块变量 我不知道为什么这种事一次又一次地发生。这个宏的工作速度也很慢。是否可以与所有Internet Explorer(IE9、IE10、IE11等)合作?有人能修这个吗 我有Office2007和IE9Vba 项目搜索宏,vba,excel,internet-explorer,Vba,Excel,Internet Explorer,我有一个Excel宏,可以从网站上搜索商品编号,并从网页上删除一些特定信息,如可用性、价格、页面URL。但在抓取了一些页面后,它给了我以下错误: 运行时错误91,未设置对象变量或带块变量 我不知道为什么这种事一次又一次地发生。这个宏的工作速度也很慢。是否可以与所有Internet Explorer(IE9、IE10、IE11等)合作?有人能修这个吗 我有Office2007和IE9 Sub xtremeExcel() Dim HTMLDoc As HTMLDocument Dim oBrowse
Sub xtremeExcel()
Dim HTMLDoc As HTMLDocument
Dim oBrowser As InternetExplorer
Dim oHTML_Element As IHTMLElement
Set oBrowser = New InternetExplorer
oBrowser.Visible = True
oBrowser.navigate "http://cpc.farnell.com/"
Do
Loop Until oBrowser.readyState = READYSTATE_COMPLETE
For i = 3 To Sheet1.Range("A:A").Find(what:="*", searchdirection:=xlPrevious).Row
Set HTMLDoc = oBrowser.document
xc = 0
Do While (HTMLDoc.getElementById("searchTerms") Is Nothing)
Application.Wait (Now() + TimeValue("00:00:01"))
xc = xc + 1
If xc > 15 Then
Exit Do
End If
Loop
Set HTMLDoc = oBrowser.document
HTMLDoc.getElementById("searchTerms").Value = Cells(i, 1).Value
HTMLDoc.getElementById("go").Click
xc = 0
flag = 0
Do While (HTMLDoc.getElementsByClassName("prodDetailAvailability")(0) Is Nothing)
Application.Wait (Now() + TimeValue("00:00:01"))
xc = xc + 1
If xc > 15 Then
Exit Do
End If
Loop
If HTMLDoc.getElementsByClassName("prodDetailAvailability")(0) Is Nothing Then
xc = 0
Do While (HTMLDoc.getElementById("totalNoResultsSlotAtTop") Is Nothing)
Application.Wait (Now() + TimeValue("00:00:01"))
xc = xc + 1
If xc > 10 Then
Exit Do
End If
Loop
flag = 2
End If
If flag <> 2 Then
Sheet1.Cells(i, 2).Value = Replace(HTMLDoc.getElementsByClassName("prodDetailAvailability")(0).innerText, "Availability: ", "")
unitprice = HTMLDoc.getElementsByClassName("unitprice")(0).innerText
If InStr(1, unitprice, "(") > 0 Then
Sheet1.Cells(i, 3).Value = Replace(Left(unitprice, InStr(1, unitprice, "(") - 1), "Unit Price: ", "")
Sheet1.Cells(i, 4).Value = Mid(unitprice, InStr(1, unitprice, "(") + 1, InStr(1, unitprice, ")") - 1 - (InStr(1, unitprice, "(")))
Else
Sheet1.Cells(i, 3).Value = unitprice
End If
Sheet1.Cells(i, 5).Value = oBrowser.LocationURL
Else
Sheet1.Cells(i, 2).Value = "Not Found"
End If
oBrowser.GoBack
Next
End Sub
Sub-xtremeExcel()
将HTMLDoc设置为HTMLDocument
作为InternetExplorer的Dim oBrowser
尺寸oHTML\U元件作为IHTML元件
Set oBrowser=新的InternetExplorer
oBrowser.Visible=True
oBrowser.navigate“http://cpc.farnell.com/"
做
循环直到oBrowser.readyState=readyState\u完成
对于i=3到Sheet1.Range(“A:A”).Find(what:=“*”,searchdirection:=xlPrevious)。行
设置HTMLDoc=oBrowser.document
xc=0
Dowhile(HTMLDoc.getElementById(“searchTerms”)什么都不是)
Application.Wait(现在()+TimeValue(“00:00:01”))
xc=xc+1
如果xc>15,则
退出Do
如果结束
环
设置HTMLDoc=oBrowser.document
HTMLDoc.getElementById(“searchTerms”).Value=单元格(i,1).Value
HTMLDoc.getElementById(“go”)。单击
xc=0
标志=0
Do While(HTMLDoc.getElementsByClassName(“prodDetailAvailability”)(0)为空)
Application.Wait(现在()+TimeValue(“00:00:01”))
xc=xc+1
如果xc>15,则
退出Do
如果结束
环
如果HTMLDoc.getElementsByClassName(“prodDetailAvailability”)(0)为空,则
xc=0
Dowhile(HTMLDoc.getElementById(“totalNoResultsSlotAtTop”)什么都不是)
Application.Wait(现在()+TimeValue(“00:00:01”))
xc=xc+1
如果xc>10,则
退出Do
如果结束
环
标志=2
如果结束
如果是标志2,那么
Sheet1.Cells(i,2).Value=Replace(HTMLDoc.getElementsByClassName(“prodDetailAvailability”)(0).innerText,“Availability:”,“”)
unitprice=HTMLDoc.GetElementsByCassName(“unitprice”)(0)。innerText
如果仪表(1,单价,“(”)大于0,则
表1.单元格(i,3).值=替换(左)(单价,仪表(1,单价,“(”)-1),“单价:”,“)
表1.单元格(i,4).值=中间(单价,单位价格,“(”)+1,单位价格,“)”)-1-(单价,单位价格,“(”))
其他的
表1.单元格(i,3).值=单价
如果结束
Sheet1.单元格(i,5).Value=oBrowser.LocationURL
其他的
表1.单元格(i,2).Value=“未找到”
如果结束
长尾蛇
下一个
端接头
tl;dr;
您可以按如下所示的方式循环;等待设置项目
函数WaitUntilReady
循环直到.document.getElementById(“sProdList”)
可以设置。这是保存要返回的信息的表。您可能希望添加一些错误处理和超时,以便循环不会冒无限循环的风险
我在searchTerms
数组中列出了2个搜索词。您可以扩展它。它将搜索词连接到URL中,因此直接搜索,而不是总是点击登陆和重新定向
注意:
如果计划进行大量搜索或循环搜索结果页面,我将研究是否有可用的API。下面只做每个页面的第一页,但已经给了您大量代码。如果尝试XHR,您的IP将被阻止,因此下面的方法是一种折衷。我很愿意放弃IE的任何解决方案
页面结果示例: 示例代码输出:
VBA:
选项显式
公共子GetInfo()
Dim IE作为InternetExplorer,一个作为HTMLTable,一个作为工作表的wsTarget,currSearch作为Long,searchTerms
Application.ScreenUpdating=False
Set IE=新的InternetExplorer
Set-wsTarget=ThisWorkbook.Worksheets(“Sheet2”)
wsTarget.UsedRange.ClearContents
searchTerms=阵列(“CCTV”、“粉丝”)
与IE
.Visible=True
ApplyHeaders wsTarget
对于currSearch=LBound(搜索术语)到UBound(搜索术语)
.导航“http://cpc.farnell.com/search?st=&searchTerms(currSearch)&aka_re=1
设置a=WaitUntilReady(即)
将所有行设置为对象,类名称()
Set allRows=a.GetElementsByCassName(“altRow”)
classNames=数组(“productImage mftrPart”、“sku”、“说明”、“可用性”、“priceFor”、“priceBreak”)
Dim i长,y长,r长,tempString长,j长,k长
r=GetLastRow(wsTarget,1)+1
对于所有行,i=0。长度为-1
对于j=LBound(类名)到UBound(类名)
对于k=0的所有行(i).getElementsByClassName(classNames(j)).Length-1
tempString=tempString&vbNewLine&TidyString(allRows(i).getElementsByClassName(classNames(j))(k).innerText)
下一个k
有目标
.Cells(r,j+1).Value=tempString
以
tempString=vbNullString
下一个j
r=r+1
接下来我
r=r+1
下一步搜索
退出
以
整洁的目标
Application.ScreenUpdating=True
端接头
公共函数GetLastRow(ByRef ws作为工作表,可选ByVal columnNumber作为Long=1)的长度为
与ws
GetLastRow=.Cells(.Rows.Count,columnNumber).End(xlUp).Row
以
端函数
公共函数TidyString(ByVal inputString作为字符串)作为字符串
TidyString=Application.WorksheetFunction.Clean(inputString)
TidyString=Trim$(Replace$(Replace$(TidyString,Chr$(10),vbNullString),vbCrLf,vbNullString))
结束函数
Option Explicit
Public Sub GetInfo()
Dim IE As InternetExplorer, a As HTMLTable, wsTarget As Worksheet, currSearch As Long, searchTerms
Application.ScreenUpdating = False
Set IE = New InternetExplorer
Set wsTarget = ThisWorkbook.Worksheets("Sheet2")
wsTarget.UsedRange.ClearContents
searchTerms = Array("CCTV", "FANS")
With IE
.Visible = True
ApplyHeaders wsTarget
For currSearch = LBound(searchTerms) To UBound(searchTerms)
.navigate "http://cpc.farnell.com/search?st=" & searchTerms(currSearch) & "&aka_re=1"
Set a = WaitUntilReady(IE)
Dim allRows As Object,classNames()
Set allRows = a.getElementsByClassName("altRow")
classNames = Array("productImage mftrPart", "sku", "description", "availability", "priceFor", "priceBreak")
Dim i As Long, y As Long, r As Long, tempString As String, j As Long, k As Long
r = GetLastRow(wsTarget, 1) + 1
For i = 0 To allRows.Length - 1
For j = LBound(classNames) To UBound(classNames)
For k = 0 To allRows(i).getElementsByClassName(classNames(j)).Length - 1
tempString = tempString & vbNewLine & TidyString(allRows(i).getElementsByClassName(classNames(j))(k).innerText)
Next k
With wsTarget
.Cells(r, j + 1).Value = tempString
End With
tempString = vbNullString
Next j
r = r + 1
Next i
r = r + 1
Next currSearch
.Quit
End With
TidySheet wsTarget
Application.ScreenUpdating = True
End Sub
Public Function GetLastRow(ByRef ws As Worksheet, Optional ByVal columnNumber As Long = 1) As Long
With ws
GetLastRow = .Cells(.Rows.Count, columnNumber).End(xlUp).Row
End With
End Function
Public Function TidyString(ByVal inputString As String) As String
TidyString = Application.WorksheetFunction.Clean(inputString)
TidyString = Trim$(Replace$(Replace$(TidyString, Chr$(10), vbNullString), vbCrLf, vbNullString))
End Function
Public Sub ApplyHeaders(ByVal wsTarget As Worksheet)
Dim headers(), i As Long
headers = Array("Manufacturer Part No", "Order Code", "Manufacturer / Description", "Avail", "Price For", "Price Ex. VAT (Inc. VAT)")
For i = LBound(headers) To UBound(headers)
wsTarget.Cells(1, i + 1).Value = headers(i)
Next i
End Sub
Public Function WaitUntilReady(ByVal IE As InternetExplorer) As HTMLTable
With IE
While .Busy Or .readyState < 4: DoEvents: Wend
Do
DoEvents
On Error Resume Next
Set WaitUntilReady = .document.getElementById("sProdList")
On Error GoTo 0
Loop While WaitUntilReady Is Nothing
End With
End Function
Public Sub TidySheet(ByVal wsTarget As Worksheet)
With wsTarget
.Rows("2:" & .Cells.Find(What:="*", After:=.Range("A1"), SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row).RowHeight = 25
.UsedRange.Columns.AutoFit
End With
End Sub