2013-10-31 74 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它會在頁面刷新之前停止(顯然)是否有轉向這個? –

相關問題