Sto scrivendo un semplice programma di screen scraping in C#, per cui ho bisogno di selezionare tutti gli input inseriti all'interno di un singolo modulo chiamato "aspnetForm" (nella pagina c'è 2 moduli e non voglio input da un altro) e tutti gli input in questo modulo sono posizionati all'interno di tabelle, div o solo al primo livello figlio di questo modulo.XPath select in HTMLAgilityPack non funziona come previsto
Così ho scritto molto semplice query XPath:
//form[@id='aspnetForm']//input
opere è tutto come previsto in tutti i browser che ho provato (Chrome, IE, Firefox) - restituisce quello che voglio.
Ma in HTMLAgilityPack non funziona affatto - SelectNodes restituisce sempre solo NULL.
Questa query che ho scritto per i test funziona bene, ma non restituisce quello che voglio. Per prima cosa selezionare tutti gli input di che sono di prima bambino per la mia forma, e forma la seconda appena di ritorno:
//form[@id='aspnetForm']/input
//form[@id='aspnetForm']
sì, lo so che io posso solo enumerare sopra i nodi da ultima query, o fare un altro SelectNodes su di essa la conseguenza, ma non voglio davvero farlo Voglio utilizzare la stessa query dei browser.
XPath è attualmente danneggiato in HTMLAgilityPack? Esistono implementazioni XPath alternative per C#?
UPDATE: Codice di prova:
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 ha implementato l'implementazione di XPath che viene utilizzata da HtmlAgilityPack (HAP non implementa il proprio motore XPath). E in effetti l'XPath di HAP funzionava bene per me, quindi suggerirei di sospettare qualcos'altro prima. – har07
Provare a salvare il 'HtmlDocument', quindi controllare se il file salvato contiene il formato HTML previsto. – har07
@ har07, contiene - l'ho provato prima di inviare una domanda. Anche i metodi "dirty workaround" funzionano, quindi non è assolutamente un problema con l'input. Aggiunto il codice di test alla domanda, in modo che tu possa testarlo da solo - NON funziona come previsto. – rufanov