Ich schreibe einfaches screen scraping-Programm in C#, für die ich alle Eingabe innerhalb eines einzigen Formulars namens "aspnetForm" (es gibt 2 Formulare auf der Seite) ausgewählt werden muss (und ich möchte keine Eingaben von einem anderen), und alle Eingaben in dieser Form werden in verschiedenen Tabellen, Divs oder nur auf der ersten untergeordneten Ebene dieser Form platziert.XPath Auswahl in HTMLAgilityPack funktioniert nicht wie erwartet
So geschrieben ich wirklich einfache XPath-Abfrage:
//form[@id='aspnetForm']//input
Es Arbeiten wie in allen Browsern zu erwarten, dass ich getestet (Chrome, IE, Firefox) - es gibt, was ich will.
Aber in HTMLAgilityPack funktioniert es überhaupt nicht - SelectNodes geben immer nur NULL zurück.
Diese Abfragen, die ich für Tests geschrieben habe, funktioniert gut, aber gibt nicht zurück, was ich will. Wählen Sie zuerst alle Eingaben ist das erste Childs für meine Form sind, und die zweite gerade Rückkehr Form:
//form[@id='aspnetForm']/input
//form[@id='aspnetForm']
Ja, ich weiß, dass ich nur Knoten von den letzten Abfrage aufzuzählen über, oder einen anderen Select machen auf ihr Ergebnis, aber Ich möchte das nicht wirklich machen. Ich möchte dieselbe Abfrage wie in Browsern verwenden.
Ist XPath derzeit in HTMLAgilityPack beschädigt? Gibt es alternative XPath-Implementierungen für C#?
UPDATE: Testcode:
using HtmlAgilityPack;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace HtmlAGPTests
{
[TestClass]
public class XPathTests
{
private const string html =
"<form id=\"aspnetForm\">" +
"<input name=\"first\" value=\"first\" />" +
"<div>" +
"<input name=\"second\" value=\"second\" />" +
"</div>" +
"</form>";
private static HtmlNode GetHtmlDocumentNode()
{
var document = new HtmlDocument();
document.LoadHtml(html);
return document.DocumentNode;
}
[TestMethod]
public void TwoLevelXpathTest() // fail - nodes is NULL actually.
{
var query = "//form[@id='aspnetForm']//input"; // what i want
var documentNode = GetHtmlDocumentNode();
var inputNodes = documentNode.SelectNodes(query);
Assert.IsTrue(inputNodes.Count == 2);
}
[TestMethod]
public void TwoSingleLevelXpathsTest() // works
{
var formQuery = "//form[@id='aspnetForm']";
var inputQuery = "//input";
var documentNode = GetHtmlDocumentNode();
var formNode = documentNode.SelectSingleNode(formQuery);
var inputNodes = formNode.SelectNodes(inputQuery);
Assert.IsTrue(inputNodes.Count == 2);
}
[TestMethod]
public void SingleLevelXpathTest() // works
{
var query = "//form[@id='aspnetForm']";
var documentNode = GetHtmlDocumentNode();
var formNode = documentNode.SelectSingleNode(query);
Assert.IsNotNull(formNode);
}
}
}
.NET verfügt über eine integrierte Implementierung von XPath, die von HtmlAgilityPack verwendet wird (HAP implementiert keine eigene XPath-Engine). Und tatsächlich funktionierte HAPs XPath für mich gut, also würde ich vorschlagen, zuerst etwas anderes zu vermuten. – har07
Versuchen Sie, das 'HtmlDocument' zu speichern, und prüfen Sie, ob die gespeicherte Datei das erwartete HTML-Format enthält. – har07
@ har07, es enthält - ich habe das vor dem Stellen der Frage getestet. Auch "dreckige Workaround" -Methoden funktionieren, also ist es absolut kein Problem mit der Eingabe. Testcode zu Frage hinzugefügt, so dass Sie es selbst testen können - es funktioniert NICHT wie erwartet. – rufanov