1

所以我正在为一些 web api 做一些自动化测试。我正在尝试查看是否可以使用 System.Windows.Forms.WebBrowser 类导航到页面,输入一些文本并按下按钮,所有这些都来自控制台。我决定使用维基百科进行测试,因为在搜索栏中输入文本并点击搜索与我正在尝试做的事情几乎相同。

我使用这个问题的代码开始。

我遇到的问题是我似乎不能将这两个动作链接在一起,1)导航到维基百科,2)在搜索框中输入文本并点击 go。它可以导航到维基百科。有人告诉我尝试使用状态机,但我不太清楚它应该是什么样子。事实上,当它第二次返回 runBrowser 方法时,行 br.Document.GetElementByID("searchInput") 会引发 InvalidCastException。所以我对那里发生的事情一无所知。我假设与在旧线程运行时创建新线程有关,但是当我杀死旧线程时,它似乎也杀死了 WebBrowser 并抛出一个错误说“断开的上下文”

这是我的代码:

static WebBrowser br = new WebBrowser();

static void runBrowserThread()
{

        var th = new Thread(() =>
        {

            br.DocumentCompleted += browser_DocumentCompleted;
            if (state == 0)
            {
                br.Navigate(new Uri("http://en.wikipedia.org/wiki/Main_Page"));
                state++;
            }
            else if (state == 1)
            {

                if (br.Document.GetElementById("searchInput") != null)
                {
                    HtmlElement search = br.Document.GetElementById("searchInput");
                    search.SetAttribute("value", searchterm);
                    foreach (HtmlElement ele in search.Parent.Children)
                    {
                        if (ele.TagName.ToLower() == "input" && ele.Name.ToLower() == "go")
                        {
                            ele.InvokeMember("click");
                            break;
                        }
                    }
                }
                else
                    Console.WriteLine("Meep");
                state++;
            }

            Application.Run();
        });
        th.SetApartmentState(ApartmentState.STA);
        th.Start();       
}

static void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    // var br = sender as WebBrowser;
    if (br.Url == e.Url)
    {
        Console.WriteLine("Natigated to {0}", e.Url);

    }
    HtmlElement search = br.Document.GetElementById("searchInput");
    Console.WriteLine(search.InnerHtml);
    Console.ReadLine();
    // Application.ExitThread();   // Stops the thread
    runBrowserThread();
    return;
}

任何关于如何安排此代码以使线程的东西玩得很好的想法将不胜感激。

4

1 回答 1

2

不,你这样做从根本上是错误的。它爆炸是因为你开始了一个新线程,永远不要那样做。您应该改为检查 DocumentCompleted 事件中的状态。所以,大致:

    var th = new Thread(() =>
    {
        state = 0;
        br.Navigate(new Uri("http://en.wikipedia.org/wiki/Main_Page"));
        Application.Run();
    }

void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    var br = sender as WebBrowser;
    if (state == 0) {
       // You are now on the main page, set the searchInput and submit click
       //...
       state = 1;
    }
    else if (state == 1) {
       // You are now on the searched page, do whatever you need to do
       //...
       // And if you are done:
       Application.ExitThread();
    }
}

如果您访问更多页面,请添加其他状态。

于 2013-03-22T00:17:28.713 回答