2013-10-31 71 views
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表示该网站的库存可用性。

没有调试运行时,它似乎完全忽视写在if条件的代码。

谢谢

+0

请谨慎使用webBrowser1.ReadyState!= WebBrowserReadyState.Complete while语句。虽然在这种情况下不太可能发生,但像这样的代码可能会创建一个无限循环,因为条件可能永远不会完成,例如保持未初始化 –

+0

我看到。但我认为那不太可能发生 –

+0

if语句中的WebBrowserReadyState值是什么?从我所能告诉的状态改变到跳出while循环所需的时间。 –

回答

1

好的,问题看起来与您设置代码的方式。你正在尝试一个接一个地做事情,这会产生一些奇怪的结果。最好是允许API(WebBrowser)告诉你发生了什么,而不是在完成之前试图查询它。

有一个循环来检查“你做了吗?”被认为是后面的练习,因为它会阻塞你的代码,并占用处理器浪费的等待循环。

你需要做的,是期待通过对web浏览器API的文档,并找出如何在web浏览器通信回调用类。 C#花费事件和Delgates的一个巨大的优势,所以我的建议是看看是否有一个事件,你在找什么。快速搜索想出了:

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语句。我告诉你,你有一个iffy while循环的原因就是出于这个确切原因。枚举值在那里,以便您可以在WebBrowser进程正在处理时查询。这在多线程软件中很有用。但是,我的猜测是,该标志被翻转到

webBrowser1.ReadyState == WebBrowserReadyState.Complete 

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

Simple state machine example in C#?

我希望这有助于!

+0

哇这对我有很大的帮助。我用你提到的偶数处理程序。它现在完美,但如何在完成后立即停止?页面不断刷新,因为在该事件处理程序结束时代码提交搜索按钮。因为我使用:private void OnDocumentCompleted(object sender,WebBrowserDocumentCompletedEventArgs e)它会继续通过代码每次文档完成 –

+0

嗯。对于搜索按钮提交,您是分配相同的事件处理程序还是重用相同的WebBrowser对象?如果是这样,只需在班级中有一个“bool formSubmitted = false”的布尔值。提交表单时翻转这个布尔值。在这个事件中,检查这是真/假,如果是,不要执行里面的逻辑。 –

+0

即时重用相同的浏览器对象。生病给布尔一个尝试。看来,即使是在循环,因为它不关注布尔语句。如果我使用webbrowser.stop它会在页面刷新之前停止(显然)是否有转向这个? –

相关问题