2011-05-25 86 views
3

我一直有Html Agility Pack的問題;WebDriver可以使用xpath找到元素,Html敏捷包不能

//*[@id='some_id'] 

//input 

然而,他們隨時變得更加複雜,那麼的Html敏捷包不能處理它:我的XPath查詢時,他們都非常簡單隻有永遠的工作。 下面是一個演示問題的示例,我使用WebDriver導航到Google,並返回傳遞給Html Agility Pack的頁面源代碼,WebDriver和HtmlAgilityPack都嘗試查找元素/節點(C#):

//The XPath query 
const string xpath = "//form//tr[1]/td[1]//input[@name='q']"; 

//Navigate to Google and get page source 
var driver = new FirefoxDriver(new FirefoxProfile()) { Url = "http://www.google.com" }; 
Thread.Sleep(2000); 

//Can WebDriver find it? 
var e = driver.FindElementByXPath(xpath); 
Console.WriteLine(e!=null ? "Webdriver success" : "Webdriver failure"); 

//Can Html Agility Pack find it? 
var source = driver.PageSource; 
var htmlDoc = new HtmlDocument { OptionFixNestedTags = true }; 
htmlDoc.LoadHtml(source); 
var nodes = htmlDoc.DocumentNode.SelectNodes(xpath); 
Console.WriteLine(nodes!=null ? "Html Agility Pack success" : "Html Agility Pack failure"); 

driver.Quit(); 

在這種情況下,WebDriver成功找到該項目,但Html Agility Pack沒有。

我知道,在這種情況下,很容易將xpath更改爲可以工作的xpath://輸入[@ name ='q'],但這隻會修復此特定示例,它是不是重點,我需要的東西,將完全或至少緊密鏡像WebDriver的xpath引擎的行爲,甚至FirePath或FireFinder加載項的Firefox。

如果WebDriver能找到它,那麼爲什麼Html Agility Pack無法找到它呢?

+1

我不得不使用HTML敏捷性包的XPath的解析很成功,所以我不知道是否可能是XPath是次優的。下面是一個適用於製作應用的例子:'.// div [@id = \「main \」] // div [@id = \「content \」] // div [@ id = \ 「title \」]' – hemp 2011-05-25 17:45:15

+0

不幸的是,我大部分時間都不是創建XPath表達式的人;我幫助管理我們的自定義WebDriver框架,因此如果QA中的某個人創建了可在WebDriver中工作的XPath表達式,那麼它也必須在Html Agility Pack中工作。上面的示例僅用於捕獲我們遇到的常見問題。 – Anders 2011-05-25 19:48:13

回答

8

您遇到的問題是與FORM元素。 HTML敏捷包handles that element differently - 默認情況下,它永遠不會報告它有孩子。

在你給的特殊例子,這個查詢確實發現目標元素:

.//div/div[2]/table/tr/td/table/tr/td/div/table/tr/td/div/div[2]/input

不過,這並沒有,所以很明顯的表單元素被絆倒了解析器:

.//form/div/div[2]/table/tr/td/table/tr/td/div/table/tr/td/div/div[2]/input

雖然這種行爲是可配置的。如果你把之前解析HTML這一行,表格會給你的子節點:

HtmlNode.ElementsFlags.Remove("form"); 
+0

太棒了!我敢打賭,如果我查看以前有問題的XPath表達式,我會發現表單節點是它的根本原因。 – Anders 2011-05-25 19:30:33