我正在编写一些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>
答案 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文件才能很好地形成。
具体而言,删除重音é
并将>
和<
替换为适当的实体:>
和<
并正确关闭<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, " <=", "<"), " > ", ">"), ";"">", ";""/>")
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**