我知道这已被多次询问,但是没有看到通过div和findind标签循环使用相同类名的明确答案。
我的第一个问题:
如果我有这样的话:
<div id="carousel">
<div id="images">
<div class="imageElement">
<img src="img/image1.jpg">
</div>
<div class="imageElement">
<img src="img/image2.jpg">
</div>
<div class="imageElement">
<img src="img/image3.jpg">
</div>
</div>
</div>
所以我想在div“images”中获取所有img Src以及imageElement类名中的其他内容,并将它们复制到excel中的某些单元格。
第二个问题: 我已经看到了两种使用VBA提取Web内容的方法,一种是使用IE浏览器而另一种是使用浏览器而使用其他代码。
Private Sub pullData_Click()
Dim x As Long, y As Long
Dim htm As Object
Set htm = CreateObject("htmlFile")
With CreateObject("msxml2.xmlhttp")
.Open "GET", "http://website.html", False
.send
htm.body.innerHTML = .responsetext
End With
End Sub
第二种方式:
Set ie = New InternetExplorer
With ie
.navigate "http://eoddata.com/stockquote/NASDAQ/AAPL.htm"
.Visible = False
While .Busy Or .readyState <> READYSTATE_COMPLETE
DoEvents
Wend
Set objHTML = .document
DoEvents
End With
Set elementONE = objHTML.getElementsByTagName("TD")
For i = 1 To elementONE.Length
elementTWO = elementONE.Item(i).innerText
If elementTWO = "08/10/12" Then
MsgBox (elementONE.Item(i + 1).innerText)
Exit For
End If
Next i
DoEvents
ie.Quit
DoEvents
Set ie = Nothing
哪一个更好,为什么?
所以,如果你能帮助我,我会很感激。
提前谢谢。
答案 0 :(得分:8)
您的第一个选项通常更可取,因为它比第二个方法快得多,它会直接向Web服务器发送请求并返回响应。这比自动化Internet Explorer(第二种选择)更有效率;自动化IE非常慢,因为你实际上只是浏览网站 - 它必然会导致更多的下载,因为它必须加载页面中的所有资源 - 图像,脚本,css文件等。它还将在页面上运行任何Javascript - 所有这些通常都没有用,你必须等到它完成才能解析页面。
然而这是一把双刃剑 - 虽然慢得多,如果你不熟悉html请求,自动化Internet Explorer比第一种方法更容易,特别是当动态生成元素或页面依赖时在AJAX上。当您需要访问要求您登录的站点中的数据时,自动化IE也更容易,因为它将为您处理相关的cookie。这并不是说第一种方法无法完成网页抓取,而是需要更深入地了解网站技术和网站架构。
第一种方法的更好选择是使用不同的对象来处理请求和响应,使用WinHTTP库提供比MSXML库更多的弹性,并且通常也会自动处理任何cookie。
至于解析数据,在第一种方法中,您使用后期绑定来创建HTML对象(htmlfile),同时这减少了对引用的需求,同时也减少了功能。例如,当使用后期绑定时,如果用户安装了IE9,则会错过添加的功能,特别是在这种情况下是getElementsByClass名称函数。
作为第三种选择(以及我的首选方法):
Dim oHtml As HTMLDocument
Dim oElement As Object
Set oHtml = New HTMLDocument
With CreateObject("WINHTTP.WinHTTPRequest.5.1")
.Open "GET", "http://www.someurl.com", False
.send
oHtml.body.innerHTML = .responseText
End With
For Each oElement In oHtml.getElementsByClassName("imageElement")
Debug.Print oElement.Children(0).src
Next oElement
'IE 8 alternative
'For Each oElement In oHtml.getElementsByTagName("div")
' If oElement.className = "imageElement" Then
' Debug.Print oElement.Children(0).src
' End If
'Next oElement
这将需要Microsoft HTML Object Library
的参考设置 - 如果用户没有安装IE9,它将失败,但这可以处理并且变得越来越不相关
答案 1 :(得分:2)
要将元素打印到单元格替换:
For Each oElement In oHtml.getElementsByClassName("imageElement")
Debug.Print oElement.Children(0).src
Next oElement
使用:
Dim wsTarget as Worksheet
dim i as Integer
i=1
set wsTarget=activeworkbook.worksheets("SomeSheet")
For Each oElement In oHtml.getElementsByClassName("imageElement")
wstarget.range("A" & i)=oElement.Children(0).src
i=i+1
Next
'更正了For
的语法错误答案 2 :(得分:2)
CSS选择器:
您还可以使用#images img[src^='img/']
中的CSS selector。
这表示ID为images
的元素包含标记名img
,其属性为src
,其值以'img/'
开头。
#
用于ID; []
表示属性; ^
开头; {{1}中的#images img
,img
。
CSS查询:
由于将匹配多个元素,因此您将使用images
的{{3}}方法,然后循环返回的document
的长度。
VBA代码:
nodeList