GeckoWebBrowser如何标记Captcha复选框(C #Windows表单)?

时间:2017-10-15 19:15:02

标签: c# winforms checkbox captcha gecko

我正在使用GeckoWebBrowser处理Windows应用程序,我正在尝试通过代码检查Captcha的复选框。 Programmaticaly我已经可以获取和设置html元素,但这个复选框我无法达到。我无法在页面的任何位置找到它。 我不是要尝试解析或解决验证码,只需选中复选框元素,然后验证是否已选中。很简单。

目前我所知道的:

在FireFox检查员中,我可以看到 enter image description here 一些明显的信息:验证码在iframe中,title =“widget recaptcha”,width = 304,height = 78。

复选框元素就在这一点上(在iframe内): enter image description here

现在,这就是我试图获取复选框,以不同方式查找id,span,div和class但没有成功...

首先,在主文档中

            //looking all elements into main Document (around 1300 elements)
            GeckoElementCollection collection = geckoWebBrowser1.Document.GetElementsByTagName("*");
        foreach (GeckoHtmlElement elem in collection)
        {
            string id = elem.Id;
            if (id == "recaptcha-anchor")
            {
                string myId = "this is my ID";         //never find this ID!
            }
            //just for debug
            string LocalName = elem.LocalName;
            string OuterHtml = elem.OuterHtml;
            string TagName = elem.TagName;
            string TextContent = elem.TextContent;
            string role = elem.GetAttribute("role");
            string value = elem.GetAttribute("value");
        }

所以,在主文档中,我无法通过ID找到任何内容。

接下来,查看iframe:

        //get the iframe works well
        foreach (GeckoIFrameElement iframe in geckoWebBrowser1.Document.GetElementsByTagName("iframe"))
        {
            //get main info about the iframe - ok
            string title = iframe.GetAttribute("title");
            if (title != null && title.ToLower().Contains("captcha"))   //got "recaptcha widget"
            {
                int x = iframe.OffsetLeft;
                int y = iframe.OffsetTop;
                int width = Convert.ToInt32(iframe.Width);
                int height = Convert.ToInt32(iframe.Height);
            }

            //inside the iframe, get all elements --> but always return null
            Gecko.Collections.IDomHtmlCollection<GeckoElement> collection2 = iframe.GetElementsByTagName("*");
            foreach (GeckoHtmlElement elem in collection2)
            {
                string id = elem.Id;
                string LocalName = elem.LocalName;
                string OuterHtml = elem.OuterHtml;
                string TagName = elem.TagName;
                string TextContent = elem.TextContent;
                string role = elem.GetAttribute("role");
                string value = elem.GetAttribute("value");
            }

            //foreach (GeckoHtmlElement elem in iframe.GetElementsByTagName("*"))             //get no elements
            //foreach (GeckoHtmlElement elem in iframe.GetElementsByTagName("input"))         //get no elements
            //foreach (GeckoHtmlElement elem in iframe.GetElementsByTagName("div"))           //get no elements
            foreach (GeckoHtmlElement elem in iframe.GetElementsByTagName("span"))           //get no elements
            {
                string id = elem.Id;
                string LocalName = elem.LocalName;
                string OuterHtml = elem.OuterHtml;
                string TagName = elem.TagName;
                string TextContent = elem.TextContent;
                string role = elem.GetAttribute("role");
            }
        }

所以,经过大量的尝试和错误后,我无法得到复选框元素,但我可以得到一些关于验证码盒的信息,比如位置和大小,虽然标题不是我预期的100%:在Firefox中title =“widget recaptcha”和GeckoWebbrowser title =“recaptcha widget”......一个奇怪的奇怪。

这让我发疯了......: - (

任何人都有一些消化我缺少的东西或我做错了什么? 有一种方法可以在iframe或完整的元素树中获取所有html元素吗?

可以做我想做的事吗?

提前致谢!

1 个答案:

答案 0 :(得分:1)

要在当前页面查找所有iframe元素,请使用GeckoWindow的Frames属性:

// this will return a collecton of all frames
var iframes = Browser.Window.Frames; 

我建议您在浏览器的DocumentCompleted事件的处理程序中执行此操作。 然后迭代这些帧。每个框架都有自己的Document元素,它实际上是其中所有元素的容器。你的验证码应该在那里。然后你可能想找到带有复选框的 div ,然后点击它,这样代码就会像这样:

foreach (var iframe in iframes)
{
    var doc = iframe.Document;
    if (doc == null)
        continue;

    var elements = doc.GetElementsByClassName("your_name");

    foreach (var element in elements)
    {
        // get the div and validate it
        var myDiv = element as GeckoDivElement;
        if(myDiv == null || !myDiv.Id.Equals("your_checkbox_id", StringComparison.InvariantCultureIgnoreCase))
            continue;

        myDiv.Click(); // click your checkbox
        break;
    }
}