如何使用VBA在div标签内的类中检索值?

时间:2015-11-28 23:07:06

标签: vba excel-vba excel

我正在编写一些VBA脚本,可以从某个网站获取航班价格。但我的代码没有得到最低的价格,它得到一个随机的价格...

我需要在下面的代码中检索一些值。

我需要检索第一个 298 U $。 我尝试过使用

cia = doc.getElementsByClassName("currency ng-binding")(0).innerText

但它不起作用。

我的代码:

<div class="box-filter cias" ng-init="opened = false">
                <h3>Cias. Aéreas</h3>
                <span>a partir de:</span>
                <div ng-class="(opened || hasFilter(AvailabilityResult.FilterOptions.AirCompanies)) ? 'opened' : 'wrapper-cias'" id="wrapper-cia" class="opened">
                    <label>
                        <input type="checkbox" class="cias-aerea chkFilterAirCompany filterControl" value="All" ng-checked="!hasFilter(AvailabilityResult.FilterOptions.AirCompanies)" ng-disabled="!hasFilter(AvailabilityResult.FilterOptions.AirCompanies)" ng-click="SetFilter($event, 'all', 'Co');">
                        <strong class="label-option full">Todas as Companhias</strong>
                    </label>

                    <!-- ngRepeat: airCompany in AvailabilityResult.FilterOptions.AirCompanies --><label ng-repeat="airCompany in AvailabilityResult.FilterOptions.AirCompanies" ng-show="airCompany.MinPrice > 0 || airCompany.MinPoint > 0" class="ng-scope">
                        <input type="checkbox" class="cias-aerea chkFilterAirCompany filterControl ng-valid ng-dirty ng-valid-parse ng-touched" ng-model="airCompany.Checked" value="true" ng-click="SetFilter($event, airCompany.CiaCode, 'Co');">
                        <strong class="label-option ng-binding">Aeroméxico</strong>
                        <span class="price ng-binding" ng-show="!UsePoints"><span class="currency ng-binding">US$</span>**298**</span>
                        <!-- ngIf: UsePoints -->
                    </label><!-- end ngRepeat: airCompany in AvailabilityResult.FilterOptions.AirCompanies --><label ng-repeat="airCompany in AvailabilityResult.FilterOptions.AirCompanies" ng-show="airCompany.MinPrice > 0 || airCompany.MinPoint > 0" class="ng-scope">
                        <input type="checkbox" class="cias-aerea chkFilterAirCompany filterControl ng-pristine ng-untouched ng-valid" ng-model="airCompany.Checked" value="false" ng-click="SetFilter($event, airCompany.CiaCode, 'Co');">
                        <strong class="label-option ng-binding">Tam</strong>
                        <span class="price ng-binding" ng-show="!UsePoints"><span class="currency ng-binding">US$</span>549</span>
                        <!-- ngIf: UsePoints -->
                    </label><!-- end ngRepeat: airCompany in AvailabilityResult.FilterOptions.AirCompanies --><label ng-repeat="airCompany in AvailabilityResult.FilterOptions.AirCompanies" ng-show="airCompany.MinPrice > 0 || airCompany.MinPoint > 0" class="ng-scope">
                        <input type="checkbox" class="cias-aerea chkFilterAirCompany filterControl ng-pristine ng-untouched ng-valid" ng-model="airCompany.Checked" value="false" ng-click="SetFilter($event, airCompany.CiaCode, 'Co');">
                        <strong class="label-option ng-binding">Delta </strong>
                        <span class="price ng-binding" ng-show="!UsePoints"><span class="currency ng-binding">US$</span>907</span>
                        <!-- ngIf: UsePoints -->
                    </label><!-- end ngRepeat: airCompany in AvailabilityResult.FilterOptions.AirCompanies --><label ng-repeat="airCompany in AvailabilityResult.FilterOptions.AirCompanies" ng-show="airCompany.MinPrice > 0 || airCompany.MinPoint > 0" class="ng-scope">
                        <input type="checkbox" class="cias-aerea chkFilterAirCompany filterControl ng-pristine ng-untouched ng-valid" ng-model="airCompany.Checked" value="false" ng-click="SetFilter($event, airCompany.CiaCode, 'Co');">
                        <strong class="label-option ng-binding">Copa </strong>
                        <span class="price ng-binding" ng-show="!UsePoints"><span class="currency ng-binding">US$</span>1.028</span>
                        <!-- ngIf: UsePoints -->
                    </label><!-- end ngRepeat: airCompany in AvailabilityResult.FilterOptions.AirCompanies --><label ng-repeat="airCompany in AvailabilityResult.FilterOptions.AirCompanies" ng-show="airCompany.MinPrice > 0 || airCompany.MinPoint > 0" class="ng-scope">
                        <input type="checkbox" class="cias-aerea chkFilterAirCompany filterControl ng-pristine ng-untouched ng-valid" ng-model="airCompany.Checked" value="false" ng-click="SetFilter($event, airCompany.CiaCode, 'Co');">
                        <strong class="label-option ng-binding">American Airlines</strong>
                        <span class="price ng-binding" ng-show="!UsePoints"><span class="currency ng-binding">US$</span>1.180</span>
                        <!-- ngIf: UsePoints -->
                    </label><!-- end ngRepeat: airCompany in AvailabilityResult.FilterOptions.AirCompanies --><label ng-repeat="airCompany in AvailabilityResult.FilterOptions.AirCompanies" ng-show="airCompany.MinPrice > 0 || airCompany.MinPoint > 0" class="ng-scope">
                        <input type="checkbox" class="cias-aerea chkFilterAirCompany filterControl ng-pristine ng-untouched ng-valid" ng-model="airCompany.Checked" value="false" ng-click="SetFilter($event, airCompany.CiaCode, 'Co');">
                        <strong class="label-option ng-binding">Gol</strong>
                        <span class="price ng-binding" ng-show="!UsePoints"><span class="currency ng-binding">US$</span>1.278</span>
                        <!-- ngIf: UsePoints -->
                    </label><!-- end ngRepeat: airCompany in AvailabilityResult.FilterOptions.AirCompanies --><label ng-repeat="airCompany in AvailabilityResult.FilterOptions.AirCompanies" ng-show="airCompany.MinPrice > 0 || airCompany.MinPoint > 0" class="ng-scope">
                        <input type="checkbox" class="cias-aerea chkFilterAirCompany filterControl ng-pristine ng-untouched ng-valid" ng-model="airCompany.Checked" value="false" ng-click="SetFilter($event, airCompany.CiaCode, 'Co');">
                        <strong class="label-option ng-binding">LAN</strong>
                        <span class="price ng-binding" ng-show="!UsePoints"><span class="currency ng-binding">US$</span>1.985</span>
                        <!-- ngIf: UsePoints -->
                    </label><!-- end ngRepeat: airCompany in AvailabilityResult.FilterOptions.AirCompanies -->

                </div>
                <a href="javascript:void(0);" ng-click="opened = !opened" ng-hide="hasFilter(AvailabilityResult.FilterOptions.AirCompanies) || AvailabilityResult.FilterOptions.AirCompanies.length <= 3" id="buttonViewAllCias" class="ver-todas ng-binding ng-hide">Ver todas as cias</a
            </div>

2 个答案:

答案 0 :(得分:1)

尝试一步一步地获得您需要的东西。您需要的价格是text-node,它位于price-span内,label位于wrapper-cia div内。

首先获取div然后获取此div的第二个孩子label。然后将span作为label的第三个孩子,最后得到text-node作为span的第二个孩子。 HTH

' Add reference to Microsoft Internet Controls (SHDocVw)
' Add reference to Microsoft HTML Object Library

Dim ie As SHDocVw.InternetExplorer
Dim doc As MSHTML.HTMLDocument
Dim url As String

url = "file:///C:/Temp/ValueInsideDiv.html"
Set ie = New SHDocVw.InternetExplorer
ie.Visible = True
ie.navigate url

While ie.Busy Or ie.readyState <> READYSTATE_COMPLETE: DoEvents: Wend

Set doc = ie.document

Dim wrapperCia As MSHTML.HTMLDivElement
Set wrapperCia = doc.getElementById("wrapper-cia")

Dim ciaLabels As MSHTML.IHTMLElementCollection ' first has index 0, second 1 etc.
Set ciaLabels = wrapperCia.Children

Dim priceLabel As MSHTML.HTMLLabelElement
Set priceLabel = ciaLabels(1)

Dim priceLabelChildren As MSHTML.IHTMLElementCollection
Set priceLabelChildren = priceLabel.Children

Dim priceSpan As MSHTML.HTMLSpanElement
Set priceSpan = priceLabelChildren(2)

Dim priceNode As MSHTML.IHTMLDOMNode
Set priceNode = priceSpan.ChildNodes(1)

Dim price As String
price = priceNode.NodeValue

Debug.Print "Price = " & price

ie.Quit
Set ie = Nothing
  

输出

Price = **298**

或者,如果您想要更简单(但更容易出错),那么就像这样:

doc.getElementsByClassName("currency ng-binding")(0).NextSibling.NodeValue

答案 1 :(得分:1)

由于格式良好的HTML成为兼容的有效XML,您可以转换原始文档,然后使用XPath query,这需要稍微清理HTML文件才能很好地形成。

具体而言,删除重音é并将><替换为适当的实体:&gt;&lt;并正确关闭<input>具有/>的节点将呈现有效的XML。当然,对于更大的html文档,可能需要更多清理,但下面使用发布的内容:

Sub ConvertAndParseWellFormedHTML()

    Dim FileNum As Integer
    Dim DataLine As String, htmlfile As String

    ' ADD VBA REFERENCE: MICROSOFT XML, v3.0 or v6.0 '
    Dim oXMLFile As New MSXML2.DOMDocument
    Dim ResultList As MSXML2.IXMLDOMNodeList

    ' READ HTML FILE LINE BY LINE, CLEANING OUT PROBLEM XML VALUES '
    FileNum = FreeFile()
    Open "C:\Path\To\Locally\Saved.html" For Input As #FileNum

    htmlfile = ""
    While Not EOF(FileNum)
        Line Input #FileNum, DataLine
        htmlfile = htmlfile + DataLine + vbNewLine

        htmlfile = Replace(Replace(Replace(htmlfile, " <=", "&lt;"), " > ", "&gt;"), ";"">", ";""/>")
        htmlfile = Replace(Replace(htmlfile, "é", "e"), "</a", "</a>")
    Wend

    ' LOAD XML CONTENT AS STRING ' 
    oXMLFile.LoadXML htmlfile

    ' EXTRACT NODES INTO LIST AND REWRITE NODES '
    ' (CHANGE NUMBER 1 FOR NODE POSITION TO GET OTHER PRICES) '
    Set ResultList = oXMLFile.SelectNodes("/div/div/label[1]/span")

    Debug.Print ResultList(0).Text        

    Set ResultList = Nothing
    Set oXMLFile = Nothing
End Sub

<强>输出

US$**298**