0
  string entry = Titleentry.Text;
        webBrowser1.Navigate("http://www.bookdepository.com/search/advanced");

        //HtmlElementCollection bookCollection;

        while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
        {
            Application.DoEvents();
        }

        HtmlElementCollection bookCollection = webBrowser1.Document.GetElementsByTagName("input");
        foreach (HtmlElement curElement in bookCollection)
        {
            if ((curElement.GetAttribute("id").ToString() == "searchTitle"))
            {
                curElement.SetAttribute("value", entry);
            }
        }



        HtmlElementCollection filterCollection = webBrowser1.Document.GetElementById("filterSortBy").GetElementsByTagName("option");
        List<HtmlElement> filterList = new List<HtmlElement>();
        foreach (HtmlElement filterItem in filterCollection) { filterList.Add(filterItem); }
        HtmlElement filterElement =
          (HtmlElement)filterList.Where(filterOption => filterOption.GetAttribute("value").Equals("price_low_high", StringComparison.InvariantCultureIgnoreCase)).SingleOrDefault();

        if (filterElement.GetAttribute("value").Equals("price_low_high"))
        {
            filterElement.SetAttribute("Selected", "price_low_high");
            filterElement.InvokeMember("click");
        }

        bookCollection = webBrowser1.Document.GetElementsByTagName("button");

        foreach (HtmlElement curElement in bookCollection)
        {
            if (curElement.GetAttribute("id").Equals("searchSubmit"))
            {
                curElement.InvokeMember("click");
            }
        }
        while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
        {
            Application.DoEvents();
        }

        MessageBox.Show("Loaded");

        System.Timers.Timer myTimer = new System.Timers.Timer(5000);
        myTimer.Enabled = true;
        myTimer.Start();
        myTimer.Stop();

        if (webBrowser1.ReadyState == WebBrowserReadyState.Complete) //from here on the code doesnt work.
        {
            HtmlElementCollection avCollection = webBrowser1.Document.GetElementById("filterAvailability").GetElementsByTagName("option");

            List<HtmlElement> avList = new List<HtmlElement>();
            foreach(HtmlElement avItem in avCollection)
            {
                avList.Add(avItem);
            }

            HtmlElement avElement =
                (HtmlElement)avList.Where(avOption => avOption.GetAttribute("value").Equals("1")).SingleOrDefault();

            if (avElement.GetAttribute("value").Equals("1"))
            {
                avElement.SetAttribute("Selected", "1");
                avElement.InvokeMember("click");
            }

            bookCollection = webBrowser1.Document.GetElementsByTagName("button");
            foreach (HtmlElement curElement in bookCollection)
            {
                if (curElement.GetAttribute("id").Equals("searchSubmit"))
                {
                    curElement.InvokeMember("click");
                }
            }
        }

这是整个代码。我尝试用计时器思维设置延迟,因为它反应太快但计时器也不起作用,所以我不确定问题可能是什么。

不起作用的代码是假设创建具有 3 个计数的 avList 并选择值 1。值 1 表示网站的 In Stock 可用性。

在没有调试的情况下运行时,它似乎完全忽略了 if 条件中编写的代码。

谢谢

4

1 回答 1

1

好的,问题似乎与您设置代码的方式有关。您正在尝试一个接一个地做一些事情,这会产生一些奇怪的结果。最好让 API (WebBrowser) 告诉您正在发生的事情,而不是在完成之前尝试查询它。

有一个循环来检查“你完成了吗?” 被认为是反向实践,因为它会阻塞您的代码并以浪费的等待循环占用处理器。

您需要做的是查看 WebBrowser API 的文档并弄清楚 WebBrowser 如何与调用类进行通信。C# 极大地利用了事件和德尔盖茨,所以我的建议是看看是否有你正在寻找的事件。快速搜索得出:

http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.ondocumentcompleted.aspx

与旋转 while 循环直到满足条件相比,这是一种更易于管理的方法。完成后让 API 通知您,然后您可以决定如何处理它。至于您的事件,以下是事件连接方式的示例:

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.onkeydown.aspx

所以你不必循环检查它们,消耗处理时间。

此外,由于您在 .NET 世界中,您可以访问 linq。您不必为了找到某些东西而写出循环。例如:

    //Note: I have not tested this code, but this is close to what it should look like
    bookCollection.where(x => x.GetAttribute("id").ToString() == "searchTitle")
              .ForEach(x => x.SetAttribute("value", entry));

我不能保证这有多快,但 LINQ 倾向于清理循环和搜索的逻辑。

======================================

如果您坚持拥有您的代码,则问题出在

     webBrowser1.ReadyState

不再处于“完成”状态。但是,您的 while 循环已经在上面检查此条件,因此您可以删除 IF 语句。我告诉你你有一个不确定的while循环的原因正是这个原因。枚举值在那里,以便您可以在 WebBrowser 进程仍在处理时对其进行查询。这在多线程软件中很有用。但是,我的猜测是旗帜被翻转到

   webBrowser1.ReadyState == WebBrowserReadyState.Complete

在页面显示之前。这可以解释为什么你的 while 循环会选择它并存在。现在,问题是它可能会将枚举翻转为未初始化,因为它已完成页面加载并断开了套接字连接。这会将其置于未初始化状态。此 API 依赖于状态机模式,并且状态的顺序可能与您认为的不同。以下是有关状态机的更多信息:

C# 中的简单状态机示例?

我希望这有帮助!

于 2013-10-31T19:44:15.190 回答