WebDriver kann Elemente mit Xpath finden, Html Agility Pack nicht

c# html-agility-pack visual-studio-2010 webdriver xpath

Frage

Ich habe ständig Probleme mit dem Html Agility Pack gehabt. Meine XPath-Abfragen funktionieren nur dann, wenn sie extrem einfach sind:

//*[@id='some_id']

oder

//input

Wenn sie jedoch immer komplizierter werden, kann Html Agility Pack nicht damit umgehen. Hier ist ein Beispiel, das das Problem demonstriert: Ich verwende WebDriver, um zu Google zu navigieren, und gebe die Seitenquelle zurück, die an Html Agility Pack übergeben wird, und WebDriver und HtmlAgilityPack versuchen, das Element / den Knoten (C #) zu finden:

//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();

In diesem Fall hat WebDriver das Element erfolgreich gefunden, Html Agility Pack jedoch nicht.

Ich weiß, ich weiß, in diesem Fall ist es sehr einfach, den XPath zu einem zu ändern, der funktioniert: // input [@ name = 'q'] , aber das wird nur dieses spezifische Beispiel beheben, was nicht der Punkt ist, Ich brauche etwas, das genau oder zumindest genau das Verhalten der Xpath-Engine von WebDriver oder sogar der FirePath- oder FireFinder-Add-Ons zu Firefox widerspiegelt.

Wenn WebDriver es finden kann, warum kann es das Html Agility Pack nicht finden?

Akzeptierte Antwort

Das Problem, mit dem Sie zu tun haben, ist das FORM-Element. HTML Agility Pack handhabt dieses Element anders - standardmäßig wird es nie melden, dass es untergeordnete Elemente hat.

In dem bestimmten Beispiel, das Sie angegeben haben, findet diese Abfrage das Zielelement:

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

Dies ist jedoch nicht der Fall, daher ist es klar, dass das Formularelement den Parser auslöst:

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

Dieses Verhalten ist jedoch konfigurierbar. Wenn Sie diese Zeile vor dem Parsing des HTML-Formulars platzieren, enthält das Formular untergeordnete Knoten:

HtmlNode.ElementsFlags.Remove("form");



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum