【问题标题】:Webbrowser click on link with OnClick attribute网络浏览器点击带有 OnClick 属性的链接
【发布时间】:2013-08-11 21:28:45
【问题描述】:

假设我有以下 HTML:

<div id="active_server">
    <div class="clearfix">
        <a href="#" onclick="return Index.submit_login('server_nlp1');">
                <span class="world_button_active">Server NL P1</span>
            </a>
        <a href="#" onclick="return Index.submit_login('server_nlp2');">
                <span class="world_button_active">Server NL P2</span>
            </a>
    </div>
</div>

现在假设我想模拟对服务器 NL P2 的点击。我知道我必须得到 HTML。所以首先我得到这样的 div:

HtmlElement active_server = webBrowser1.Document.GetElementById("active_server").GetElementsByTagName("div")[0];

但是我的问题如下:

我如何遍历元素并在 Onclick 中搜索我必须点击的链接(注意,onclick 是可变的,所以我不能做索引和点击或类似的事情。我真的需要比较onclick或者span中的文字)

我对这种类型的编程很陌生。

编辑 1 我真的不知道元素在什么地方,因为它可以改变(有时有更多的服务器,我必须找到合适的服务器......)

编辑 2

HTML 如下所示:

<div id="active_server">
    <p class="pseudo-heading">Op welke wereld wil je je aanmelden?</p>
    <div class="clearfix">
        <a href="#" onclick="return Index.submit_login('server_nl33');">
        <span class="world_button_active">Wereld 33</span>
        </a>
        <a href="#" onclick="return Index.submit_login('server_nlp1');">
        <span class="world_button_active">Casual</span>
        </a>
    </div>

    <div class="clearfix">
        <a href="#" onclick="return Index.submit_login('server_nl34');">
        <span class="world_button_inactive">Wereld 34</span>
        </a>
    </div>

    <p class="pseudo-heading" id="show_all_server">
        <a href="#" onclick="$('#show_all_server').hide();$('#inactive_server_list').show();return false">Toon alle werelden</a>
    </p>
</div>

【问题讨论】:

    标签: c# onclick click webbrowser-control


    【解决方案1】:

    我的猜测:您正在尝试通过文本查找要单击的 A 链接,该链接包含在该链接的内部 SPAN 中。

    试试这个:

    HtmlElement active_server = webBrowser1.Document.GetElementById("active_server").GetElementsByTagName("div")[0];
    HtmlElement link = null;
    if (FindLinkToClick(active_server, "Server NL P1", ref link)
    {
      link.InvokeMember("click", null);
    }
    
    // FindLinkToClick
    
    bool FindLinkToClick(HtmlElement root, string text, ref HtmlElement found)
    {
        foreach (var child in root.Children)
        {
            var element = (HtmlElement)child;
            if (element.InnerText == text) 
            {
                found = element.Parent;
                return true;
            }
            if (FindLinkToClick(element, text, ref found))
                return true;
        }
        return false;
    }
    

    [已编辑]

    如果您确定要查找的字符串(例如“Server NL P1”)是唯一的,则可以使用 webBrowser1.WB.Document.Body 作为 root 进行搜索:

    HtmlElement link = null;
    if (FindLinkToClick(webBrowser1.WB.Document.Body, "Server NL P1", ref link))
    {
      link.InvokeMember("click", null);
    }
    

    [已编辑]

    我刚刚使用下面的 HTML 对其进行了测试,它可以正常工作。注意&lt;a href="#" onclick="alert('clicked!')"&gt;,我确实看到“点击了!”警报。

    <div id="active_server">
        <p class="pseudo-heading">Op welke wereld wil je je aanmelden?</p>
        <div class="clearfix">
            <a href="#" onclick="alert('clicked!')">
            <span class="world_button_active">Wereld 33</span>
            </a>
            <a href="#" onclick="return Index.submit_login('server_nlp1');">
            <span class="world_button_active">Casual</span>
            </a>
        </div>
    
        <div class="clearfix">
            <a href="#" onclick="return Index.submit_login('server_nl34');">
            <span class="world_button_inactive">Wereld 34</span>
            </a>
        </div>
    </div>
    

    我这样称呼它:

    HtmlElement link = null;
    if (FindLinkToClick(this.webBrowser1.Document.Body, "Wereld 33", ref link))
      link.InvokeMember("click", null);
    

    [更新]

    代码无需修改即可使用您提供的链接。也许,您需要确保文档已完全加载,如下所示:

    bool _loaded = false;
    
    public Form1()
    {
        InitializeComponent();
    
        this.WB.DocumentCompleted += WB_DocumentCompleted;
    }
    
    void WB_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        if (_loaded)
            return;
        _loaded = true;
    
        HtmlElement link = null;
        if (FindLinkToClick(this.WB.Document.Body, "Wereld 33", ref link))
        {
          link.InvokeMember("click", null);
        }
    }
    
    void Form1_Load(object sender, EventArgs e)
    {
        this.WB.Navigate(@"http://scriptsenprogs.nl/twmc.html");
    }
    

    【讨论】:

    • 嗯,看起来不错...但是我得到一个对象引用错误(active_server 是null...)我唯一能想到的是 div 是用用户名/密码发生后的 JScript ......这有问题吗??? -btw-感谢您的思考/回答:D
    • 没问题,根据您的意见,这就是我所能提供的帮助。我们不能把它变成交互式调试会话。希望我给了你一个很好的凝视点。
    • 是的,我想你是对的......我已经清理了,但仍然是 null 问题......我明天会把头撞在墙上,当我找到答案时将发布它,以便其他人幸运。我将把这个问题留几天(以防万一......)但我认为赏金会交给你;)谢谢,祝你有一个美好的(编码)日
    • 不用担心,很高兴它为您解决了 :) 请注意,该代码确实依赖于:1) SPAN 中的文本是唯一的,2) SPAN 是 A 元素的直接子元素。
    • 感谢您的提醒;)据我所知,这不会是一个问题。如果是的话,我认为我现在可以解决这个问题(感谢你和你的代码;P)
    【解决方案2】:
    webBrowser1.DocumentCompleted += (s, e) =>
    {
        HtmlElement active_server = webBrowser1.Document.GetElementById("active_server").GetElementsByTagName("div")[0];
        var a = active_server.GetElementsByTagName("a")[0];
        a.InvokeMember("click", null);
    };
    

    【讨论】:

    • 对不起,我不清楚。我真的不知道元素在什么地方,因为它可以改变(有时有更多的服务器,我必须找到合适的服务器......)所以这对特定问题不起作用(找到点击右链接)。不过还是谢谢 ;)
    猜你喜欢
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    • 2014-03-08
    • 1970-01-01
    相关资源
    最近更新 更多