首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关键对象WebView如何在HTML中导航?

关键对象WebView如何在HTML中导航?
EN

Stack Overflow用户
提问于 2020-04-27 09:13:37
回答 2查看 2.7K关注 0票数 2

我正在使用基本对象库来读取网站。

我以前在上也这样做过,但是这次该网站没有使用,所以我不得不更改为EO webView。

这部纪录片太穷了,我找不到答案。

在webbrowser中,您有一个HtmlElementCollection,它原则上是一个HtmlElement列表。在这些元素上,您可以读取属性或创建一个InvokeMember("Click"),并在子元素/父元素中导航。

EO WebView与这个HtmlElementCollection / HtmlElement的等价性是什么?如何在HTML树中导航?

顺便说一句:我正在和C#一起使用它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-04 22:52:12

请参阅文档:这里这里这里

本质上,您必须依赖于执行JavaScript的能力。

您可以通过几种方式访问文档JavaScript对象:

代码语言:javascript
复制
JSObject document = (JSObject)_webView.EvalScript("document");

//or: Document document = _webView.GetDOMWindow().document;   

GetDOMWindow()返回一个EO.WebBrowser.DOM.Document实例;该类型从JSObject派生,并提供一些额外的属性(例如,有一个body属性可以使您获得EO.WebBrowser.DOM.Element类型的BODY元素)。

但是总的来说,这些提供的API并不是更丰富。

您可以这样使用JSObject:

代码语言:javascript
复制
// access a property on the JavaScript object:
jsObj["children"]    

// access an element of an array-like JavaScript object:
var children = (JSObject)jsObj["children"];
var first = (JSObject)children[0];

// (note that you have to cast; all these have the `object` return type)

// access an attribute on the associated DOM element
jsObj.InvokeFunction("getAttribute", "class")

// etc.

这有点微妙,但您可以编写一些扩展方法来简化您的生活(不过,请参阅下面关于性能的说明):

代码语言:javascript
复制
public static class JSObjectExtensions
{
    public static string GetTagName(this JSObject jsObj)
    {
        return (jsObj["tagName"] as string ?? string.Empty).ToUpper();
    }

    public static string GetID(this JSObject jsObj)
    {
        return jsObj["id"] as string ?? string.Empty;
    }

    public static string GetAttribute(this JSObject jsObj, string attribute)
    {
        return jsObj.InvokeFunction("getAttribute", attribute) as string ?? string.Empty;
    }

    public static JSObject GetParent(this JSObject jsObj)
    {
        return jsObj["parentElement"] as JSObject;
    }

    public static IEnumerable<JSObject> GetChildren(this JSObject jsObj)
    {
        var childrenCollection = (JSObject)jsObj["children"];
        int childObjectCount = (int)childrenCollection["length"];
        for (int i = 0; i < childObjectCount; i++)
        {
            yield return (JSObject)childrenCollection[i];
        }
    }

    // Add a few more if necessary
}

然后你可以做这样的事情:

代码语言:javascript
复制
private void TraverseElementTree(JSObject root, Action<JSObject> action)
{
    action(root);
    foreach(var child in root.GetChildren())
        TraverseElementTree(child, action);
}

下面是一个如何使用此方法的示例:

代码语言:javascript
复制
TraverseElementTree(document, (currentElement) =>
{
    string tagName = currentElement.GetTagName();
    string id = currentElement.GetID();
    if (tagName == "TD" && id.StartsWith("codetab"))
    {
        string elementClass = currentElement.GetAttribute("class");
        // do something...
    } 
});

但是,同样地,它有点微妙--虽然这看起来相当好,但是您需要进行一些实验,以找到任何可能导致错误的棘手部分,并弄清楚如何修改方法,使其更加稳定。

关于业绩的说明

另一种选择是在大多数元素处理中使用JavaScript,只返回需要在C#代码中使用的值。根据逻辑的复杂程度,这在某些情况下可能会更有效,因为它将导致一个浏览器引擎往返,因此如果性能成为问题,则需要考虑。(请参见性能部分这里。)

票数 2
EN

Stack Overflow用户

发布于 2021-10-19 08:23:27

由于这是处理EO.WebBrowser的元素/子问题的罕见问题之一,而且由于我对VB.NET更感兴趣,所以我很难完成上述工作。我花了相当长的时间才弄明白这一点,所以对于所有对VB.NET更感兴趣的人来说,下面是一些VB的等效工具。

访问文档并检索带有子元素的元素:

代码语言:javascript
复制
win = WebView1.GetDOMWindow()
doc = win.document
Dim element As EO.WebBrowser.DOM.Element = doc.getElementById("ddlSamples")

访问类似数组的对象的元素:

代码语言:javascript
复制
Dim children = CType(element("children"), EO.WebBrowser.JSObject)
Dim childrenCount As Integer = CInt(children("length"))

获取元素中所选的选项-子元素,并获取子元素的innerText:

代码语言:javascript
复制
    Dim child As EO.WebBrowser.JSObject
    Dim txt As String = Nothing
    For c = 0 To childrenCount - 1
        child = CType(children(c), EO.WebBrowser.JSObject)
        If GetAttribute(child, "selected") = "selected" Then
            txt = CStr(child("text"))
            Exit For
        End If
    Next

当然,声明'GetAttribute‘函数:

代码语言:javascript
复制
Public Shared Function GetAttribute(ByVal jsObj As EO.WebBrowser.JSObject, ByVal attribute As String) As String
    Return If(TryCast(jsObj.InvokeFunction("getAttribute", attribute), String), String.Empty)
End Function

希望人们能从中受益。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61455398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档