【问题标题】:How to correctly write a CSS Attribute selector to extract all id attributes?如何正确编写 CSS 属性选择器来提取所有 id 属性?
【发布时间】:2019-05-10 16:51:11
【问题描述】:

情况:

我目前正在尝试在 VBA 中重现具有 [attr] 语法的属性选择器,该选择器来自给定 here 的 CSS 选择器练习。

选择器旨在根据给定属性的值选择元素。

预期结果:

在我包含的 html 示例中,尝试使用 html.querySelectorAll("[id]") 获取 ALL id 属性的预期结果在运行时以黄色突出显示。

问题:

我得到的不仅仅是与id 元素相关的信息——黄色突出显示的位——我得到了更多的文本。看起来几乎所有东西都有一些重复的材料。

我尝试过的:

  1. 我已经阅读了大量关于此的 CSS 资源。它们都声明了相同的语法。 *参见示例参考。我还没有找到一个很好匹配的 VBA 示例,所以我可能没有正确转换语法。
  2. 根据上述情况,仅作为测试,我尝试更改选择器语法以定位特定的id。效果很好。

例如:

 Set a = html.querySelectorAll("[id=""my-Address""]")

在我的代码示例中,这会产生以下预期值:

<p id="my-Address">I live in Duckburg</p>
  1. 我尝试从[id] 中删除[],它不会在即时窗口中打印任何内容。
  2. 这个SO question 有一个答案提到我正在使用的浏览器 Chrome 与某些 CSS 选择器存在问题,但我认为这不适用于我的场景。

问题:

如何在 VBA 中正确编写 CSS 选择器,以从给定的 webpage 中提取所有具有 id 属性的元素?

代码:

Option Explicit

'[attribute] [target]  Selects all elements with a target attribute e.g. [id]

Public Sub Test13()
    Dim html As MSHTML.HTMLDocument, i As Long
    Set html = GetTestHTML()
    Dim a As Object
    'Set a = html.querySelectorAll("[id=""my-Address""]")
    Set a = html.querySelectorAll("[id]")

    For i = 0 To a.Length - 1
        Debug.Print a(i).innerText
    Next i
End Sub

Public Function GetTestHTML(Optional ByVal url As String = "https://www.w3schools.com/cssref/trysel.asp") As HTMLDocument
    Dim http As New XMLHTTP60
    Dim html As New HTMLDocument
    With http                                    'Set http = CreateObject("MSXML2.XMLHttp60")
        .Open "GET", url, False
        .send
        html.body.innerHTML = .responseText
        Set GetTestHTML = html
    End With
End Function

HMTL 预期结果为黄色:

<div class="noSel">
<h1><span class="markup">&lt;h1&gt;</span>Welcome to My Homepage<span class="markup">&lt;/h1&gt;</span></h1>

<div id="helpIntro">
<span class="markup">&lt;div class="intro"&gt;</span>
<div class="intro">
<p style="margin-top:4px;"><span class="markup">&lt;p&gt;</span>My name is Donald <span id="Lastname" style="border-color: rgb(255, 102, 102); background-color: rgb(255, 255, 153);"><span class="markup">&lt;span id="Lastname"&gt;</span>Duck.<span class="markup">&lt;/span&gt;</span></span><span class="markup">&lt;/p&gt;</span></p>
<p id="my-Address" style="border-color: rgb(255, 102, 102); background-color: rgb(255, 255, 153);"><span class="markup">&lt;p id="my-Address"&gt;</span>I live in Duckburg<span class="markup">&lt;/p&gt;</span></p>
<p style="margin-bottom:4px;"><span class="markup">&lt;p&gt;</span>I have many friends:<span class="markup">&lt;/p&gt;</span></p>
</div>
<span class="markup">&lt;/div&gt;</span>
</div>

<br>
<div class="helpUl" style="border-color: rgb(255, 102, 102); background-color: rgb(255, 255, 153);">
<span class="markup">&lt;ul id="Listfriends&gt;</span>
<ul id="Listfriends" style="margin-top:0px;margin-bottom:0px;">

<li><span class="markup">&lt;li&gt;</span>Goofy<span class="markup">&lt;/li&gt;</span></li>
<li><span class="markup">&lt;li&gt;</span>Mickey<span class="markup">&lt;/li&gt;</span></li>
<li><span class="markup">&lt;li&gt;</span>Daisy<span class="markup">&lt;/li&gt;</span></li>
<li><span class="markup">&lt;li&gt;</span>Pluto<span class="markup">&lt;/li&gt;</span></li>
</ul>       
<span class="markup">&lt;/ul&gt;</span>
</div>

<ul style="display:none;"></ul>
<p><span class="markup">&lt;p&gt;</span>All my friends are great!<span class="markup">&lt;br&gt;</span><br>But I really like Daisy!!<span class="markup">&lt;/p&gt;</span></p>

<p lang="it" title="Hello beautiful"><span class="markup">&lt;p lang="it" title="Hello beautiful"&gt;</span>Ciao bella<span class="markup">&lt;/p&gt;</span></p>


<h3><span class="markup">&lt;h3&gt;</span>We are all animals!<span class="markup">&lt;/h3&gt;</span></h3>

<p><span class="markup">&lt;p&gt;</span><span><b><span class="markup">&lt;b&gt;</span>My latest discoveries have led me to believe that we are all animals:<span class="markup">&lt;/b&gt;</span></b></span><span class="markup">&lt;/p&gt;</span></p>

<div class="helpTable" style="width:220px;">
<span class="markup">&lt;table&gt;</span>
<ul style="display:none;"></ul>
  <div class="noSel" style="margin-top:10px;">

参考资料:

  1. Mozilla:CSS selectors
  2. w3schools CSS Selector Reference
  3. VBA/DOM - Get elements based on attribute
  4. Unable to get CSS Attribute selector to work
  5. Chrome and CSS attribute selector

项目参考:

*通过 VBE > 工具 > 参考

【问题讨论】:

  • 这个"[id='my-Address']"或者只是这个"[id=my-Address]"怎么样
  • @TemaniAfif 谢谢。我想要所有的 id 而不仅仅是一个特定的。那只是为了表明我可以选择一个目标 ID。很抱歉有任何混淆。

标签: html css vba web-scraping css-selectors


【解决方案1】:

原来有两个错误需要纠正。

  1. 源网站 HTML 缺少 &lt;ul id="Listfriends&gt; 部分中的结束 "。这应该是&lt;ul id="Listfriends"&gt;。这意味着 CSS 选择器会进行匹配。
  2. 我从页面中获取了所有 HTML,并询问实际上我只需要特定 iframe 中的 HTML,以便仅使用预期的 ID。

代码:

Option Explicit
Public Sub GetInfo()
    Dim html As MSHTML.HTMLDocument, i As Long
    Set html = GetTestHTML()
    Dim a As Object
    html.body.innerHTML = html.querySelector("#iframeResult").document.getElementById("selectorResult").innerHTML
    Set a = html.querySelectorAll("[id]")

    For i = 0 To a.Length - 1
        Debug.Print a(i).innerText
    Next i
End Sub

Public Function GetTestHTML(Optional ByVal url As String = "https://www.w3schools.com/cssref/trysel.asp") As HTMLDocument
    Dim http As New XMLHTTP60
    Dim html As New HTMLDocument
    With http                                    'Set http = CreateObject("MSXML2.XMLHttp60")
        .Open "GET", url, False
        .send
        html.body.innerHTML = Replace(.responseText, """Listfriends", """Listfriends""")
        Set GetTestHTML = html
    End With
End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-30
    • 2020-01-02
    • 2012-12-08
    • 2019-05-24
    • 2015-12-28
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多