代码之家  ›  专栏  ›  技术社区  ›  Cyrill

是否有可能解决网站上没有ID的元素?

  •  2
  • Cyrill  · 技术社区  · 6 年前

    在Vb中。net和Webbrowser,我通常使用 GetElementById 地址,例如按钮。我知道有 GetElementFromPoint ,我觉得这非常困难。

    当ID未知时,有没有更好、更简单的方法?

    2 回复  |  直到 6 年前
        1
  •  2
  •   David    6 年前

    您需要使用某种类型的选择器。

    这个 GetElementByID 方法工作得最好,因为如果HTML文件格式正确,那么应该只有一个元素具有该唯一ID。

    这个 GetElementFromPoint 将基于文档的X、Y坐标返回元素,这最好用于文档的单击事件。

    这个 GetElementByTagName 如果您知道元素的标记类型,name将返回元素和作品的集合,例如 <button>...</button> <p>...</p> . 为了帮助缩小所需元素的范围,您需要遍历返回的集合,并比较元素的属性(如果您知道它们各自的值)或元素的文本(通过InnerHTML属性)。

    最后也是最不有效的方法是 All 属性,该属性返回文档中的每个元素。这种方法效果最差的原因是,至少对于GetElementByTagName,您可以根据标记的名称缩小集合的范围。

    但是,假设您有以下标记:

    <body>
      <p>Look at my super complex HTML markup.</p>
      <button>Click Me</button>
      <button>No, click me!</button>
    </body>

    然后,您可以使用以下命令获得显示“单击我”的按钮标签:

    Dim click_me As HtmlElement = WebBrowser1.Document.GetElementByTagName("button").SingleOrDefault(Function(e) e.InnerHtml = "Click Me")
    
        2
  •  2
  •   Visual Vincent    5 年前

    鉴于这个问题时不时被问到,我会看看是否能一劳永逸地解决这个问题。以下是关于如何查找没有ID的元素的更广泛的指南:

    -基础知识-

    您可以使用许多内置属性和方法来标识元素。最常见的包括:

    这些方法和属性都可以以不同的方式用于标识元素,如下例所示。

    注: 我省略了 HtmlElement.OuterText 因为它的行为有点奇怪,我不能百分之百确定它到底做了什么。


    -查找无ID元素的示例-

    下面是一组示例,说明如何使用前面提到的方法和属性来查找要查找的元素。


    按类查找元素(-名称)

    根据其查找和元素 class 属性,您必须迭代所有元素并检查 GetAttribute("className") 在每个上。如果事先知道元素类型(标记名),可以通过首先获取所有元素的集合来缩小搜索范围 那种类型的 使用 HtmlDocument.GetElementsByTagName() 而不是 HtmlDocument.All .

    HTML代码:

    <div class="header">
        <div id="title" class="centerHelper">
            <img id="logo" src="img/logo.png"/>
        </div>
        <p class="headerContent">
            Hello World!
        </p>
    </div>
    

    要定位的元素:

    <p class="headerContent">
    

    VB。网络代码:

    'Iterate all elements.
    For Each Element As HtmlElement In WebBrowser1.Document.All
        If Element.GetAttribute("className") = "headerContent" Then
            'Found. Do something with 'Element'...
            Exit For 'Stop looping.
        End If
    Next
    


    基于属性查找元素,位于另一个元素内(ID为)

    为了根据子元素的一个属性查找子元素,其中子元素位于父元素(具有ID)内,您只需通过其ID获取父元素,然后迭代其所有子元素。

    HTML代码:

    <select id="items" class="itemsList">
        <option value="2">Apple</option>
        <option value="3">Orange</option>
        <option value="5">Banana</option>
    </select>
    

    要定位的元素:

    <option value="5">Banana</option>
    

    VB。网络代码:

    'Iterate all children of the element with ID "items".
    For Each Element As HtmlElement In WebBrowser1.Document.GetElementByID("items").Children
        If Element.getAttribute("value") = "5" Then
            'Found. Do something with 'Element'...
            Exit For 'Stop looping.
        End If
    Next
    


    基于属性查找元素,位于另一个元素内部(无ID)

    根据子元素的一个属性查找子元素,其中子元素位于父元素内部(即 有一个ID)您首先必须创建一个外部循环来查找 父母亲 要素然后,找到后,可以开始迭代子级。

    HTML代码:

    <select class="itemsList">
        <option value="2">Apple</option>
        <option value="3">Orange</option>
        <option value="5">Banana</option>
    </select>
    

    要定位的元素:

    <选项值=“5”>香蕉</选项(>);
    

    VB。网络代码:

    'Variable keeping track of whether we found the element we're looking for or not.
    Dim ElementFound As Boolean = False
    
    'Outer loop, looking for the parent object (<select class="itemsList">).
    For Each Element As HtmlElement In WebBrowser1.Document.GetElementsByTagName("select") 'Iterate all <select> tags. You can use Document.All here as well.
        If Element.getAttribute("className") = "itemsList" Then
    
            'Parent found.
            'Inner loop, looking for the child element we want (<option value="5">Banana</option>).
            For Each OptionElement As HtmlElement In Element.GetElementsByTagName("option")
                If OptionElement.GetAttribute("value") = "5" Then
                    'Found. Do something with 'OptionElement'...
    
                    ElementFound = True
                    Exit For 'Exit the inner loop.
                End If
            Next
    
            'Exit the outer loop if we found the element we're looking for.
            If ElementFound Then Exit For
    
        End If
    Next
    


    根据元素的 InnerText

    在某些情况下,您要定位的元素没有任何属性,或者与站点上的许多其他元素过于相似。在这种情况下,如果其内容始终相同,则可以通过 标记模板 InnerHtml 属性。

    HTML代码:

    <h1>Important information</h1>
    <p>Please read this information through <b>carefully</b> before continuing.</p>
    
    <h2>Copyrighted material<h2>
    <p>All material (text, images, video, etc.) on this site are <b>copyrighted</b> to COMPANY NAME.</p>
    

    要定位的元素:

    <h2>Copyrighted material<h2>
    

    VB。网络代码:

    For Each Element As HtmlElement In WebBrowser.Document.All
        If Element.InnerText = "Copyrighted material" Then
            'Found. Do something with 'Element'...
            Exit For 'Stop looping.
        End If
    Next
    


    根据元素的 InnerHtml

    根据元素的 InnerHtml 与根据其 标记模板 除此之外,您现在检查的字符串还包括HTML代码。

    HTML代码:

    <h1>重要信息</h1>
    <p>请通过阅读此信息(<b>小心</b>继续之前</p>
    
    <h2>受版权保护的材料<h2>
    <p>本网站上的所有材料(文本、图像、视频等)均为<b>版权所有</b>至公司名称</p>
    

    要定位的元素:

    <p>All material (text, images, video, etc.) on this site are <b>copyrighted</b> to COMPANY NAME.</p>
    

    VB。网络代码:

    'Iterate all <p> tags.
    For Each Element As HtmlElement In WebBrowser.Document.GetElementsByTagName("p")
        If Element.InnerHtml.Contains("<b>copyrighted</b>") Then
            'Found. Do something with 'Element'...
            Exit For 'Stop looping.
        End If
    Next