如何在 VBA 中获取标签的内部文本,不包括嵌套标签中的文本?

Posted

技术标签:

【中文标题】如何在 VBA 中获取标签的内部文本,不包括嵌套标签中的文本?【英文标题】:How to get innerText of a tag in VBA excluding text from nested tags? 【发布时间】:2020-11-21 23:39:32 【问题描述】:

我正在使用 VBA 进行网页抓取。下面是html结构和我的VBA代码。

当我运行它时,我得到了这个文本ETA : 2020-08-26 (Reference only, the date will be updated according to shipments).

但我只想从中刮取日期2020-08-26

 <div style="font-size: 14px;">
     <span class="label" style="font-weight: bolder; font-size: 13px;">ETA : </span>
     <br>
     2020-08-26 
    <span style="color: red; font-size: 12px;">(Reference only, the date will be updated according to 
     shipments).</span>
</div>

VBA 代码>

 Dim ie As New InternetExplorer
    Dim doc As New HTMLDocument
    
    ie.navigate "http://127.0.0.1/wordpress/sample-page/"
    Do
    DoEvents
    Loop Until ie.readyState = READYSTATE_COMPLETE
    
    Set doc = ie.document
    Set elems = doc.getElementsByTagName("div")
    MsgBox elems(33).innerText

【问题讨论】:

获得完整字符串后,使用InstrMid 定位:( 的位置以隔离日期,然后使用Trim 删除前导和尾随空格,然后将其设置为日期变量。 【参考方案1】:

此代码查找####-##-## 形式的任何日期。

Cells.Clear
s = "ETA : 2020-08-26 (Reference only, the date will be updated according to shipments)."
ReDim a(1 To Len(s))
For i = 1 To Len(s)
a(i) = IIf(Mid(s, i, 1) Like "#", "#", Mid(s, i, 1))
Next i
fd = "####-##-##"
Cells(1, 1) = s
aa = Join(a, "")
Cells(2, 1) = aa
Cells(3, 1) = Mid(s, InStr(aa, fd), Len(fd))
Cells(3, 1).NumberFormat = "yyyy-mm-dd"

首先它将字符串拆分为一个数组,并将所有数字替换为#。然后它使用InStr 找到与模式模板fd 的匹配,并使用匹配的返回值返回实际日期。

【讨论】:

【参考方案2】:

获得字符串后,您可以使用InstrMidTrim 的组合来获取日期:

Sub test()
  Dim sSource As String
  Dim nStart As Integer
  Dim nEnd As Integer
  Dim sResult As String
  Dim dtDate As Date
  
  sSource = "ETA : 2020-08-26 (Reference only, the date will be updated according to shipments)"
  nStart = InStr(sSource, ":")
  nEnd = InStr(sSource, "(")
  
  sResult = Trim$(Mid$(sSource, nStart + 1, nEnd - nStart - 1))
  If IsDate(sResult) Then
    dtDate = CDate(sResult)
    MsgBox "Success: " & dtDate
  Else
    MsgBox sResult & " is not a date"
  End If

End Sub

【讨论】:

【参考方案3】:
Dim html, divs, d, c

Set html = CreateObject("htmlfile")
html.body.innerHTML = "<div style='font-size: 14px;'><span class='label' style='font-weight: bolder; font-size: 13px;'>ETA : </span>" & _
 "<br>2020-08-26" & _
"<span style='color: red; font-size: 12px;'>(Reference only, the date will be updated according toshipments).</span>" & _
 "</div>"

Set divs = html.getElementsByTagName("div")
For Each d In divs
    For Each c In d.ChildNodes
        Debug.Print TypeName(c), c.nodeName, c.NodeValue
    Next c
Next d

输出:

HTMLSpanElement             SPAN          Null
HTMLBRElement               BR            Null
DispHTMLDOMTextNode         #text         2020-08-26
HTMLSpanElement             SPAN          Null

【讨论】:

【参考方案4】:

您可以通过字符串操作或通过 DOM 的路径来实现。这是带有路径的解决方案。

Sub SelectFromDropdown()

  Dim url As String
  Dim browser As Object
  Dim nodeDiv As Object
  
  url = "Your URL Here"
  
  'Initialize Internet Explorer, set visibility,
  'call URL and wait until page is fully loaded
  Set browser = CreateObject("internetexplorer.application")
  browser.Visible = True
  browser.navigate url
  Do Until browser.readyState = 4: DoEvents: Loop
  
  'Istead of (0) it's (33) in your code
  'However, I do not recommend the use of such high indices,
  'as they can lead to unstable behaviour. Just add a div tag
  'before the index and the macro will not work anymore. This
  'does not apply if you loop through an HTML section that has
  'been selected as a container of exactly these div tags.
  Set nodeDiv = browser.document.getElementsByTagName("div")(0)
  
  'To get only the date you can go through the DOM path
  'You want a text node of the DOM (Document Object Model)
  'So innertext doesn't work. You need the NodeValue
  MsgBox nodeDiv.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NodeValue
End Sub

【讨论】:

在哪一行?用你的 html sn-p 我的代码做你想做的事。你试过braX的代码吗?选择哪种方式并不重要。 'MsgBox nodeDiv.FirstChild.NextSibling.NextSibling.NextSibling.NextSibling.NodeValue' 这行给出了错误。但是感谢您的努力。我没有尝试过“brax's”代码我使用“JMP's”代码,因为我还想在从网站上抓取日期后更改数字格式。 我刚刚使用了您的代码中出现错误的那一行。可能是因为我收到了错误。

以上是关于如何在 VBA 中获取标签的内部文本,不包括嵌套标签中的文本?的主要内容,如果未能解决你的问题,请参考以下文章

使用css选择器从元素中获取文本,不包括嵌套元素内的文本

vba如何对选取区域设置边框线颜色,边框包括外部边框和内部的。

web第一章

如何在 VBA 中获取对文本框控件的引用而不是文本框的值

如何使用带有标签的目标 c 从文本字段访问文本值?

HTML标签书写格式是啥