Tentativo di analizzare un documento HTML ed estrarre alcuni elementi (eventuali collegamenti a file di testo).Analisi del documento HTML: espressione regolare o LINQ?
La strategia corrente consiste nel caricare un documento HTML in una stringa. Quindi trova tutte le istanze di link a file di testo. Potrebbe essere qualsiasi tipo di file, ma per questa domanda, è un file di testo.
L'obiettivo finale è disporre di un elenco di oggetti stringa IEnumerable
. Quella parte è facile, ma l'analisi dei dati è la domanda.
<html>
<head><title>Blah</title>
</head>
<body>
<br/>
<div>Here is your first text file: <a href="http://myServer.com/blah.txt"></div>
<span>Here is your second text file: <a href="http://myServer.com/blarg2.txt"></span>
<div>Here is your third text file: <a href="http://myServer.com/bat.txt"></div>
<div>Here is your fourth text file: <a href="http://myServer.com/somefile.txt"></div>
<div>Thanks for visiting!</div>
</body>
</html>
Gli approcci iniziali sono:
- carico la stringa in un documento XML, e attaccano in modo LINQ to XML.
- creare un'espressione regolare, a cercare una stringa che inizia con
href=
, e termina con.txt
la domanda che:
- cosa sarebbe quello sguardo regex come? Sono un principiante regex e questo fa parte del mio apprendimento regex.
- quale metodo useresti per estrarre un elenco di tag?
- quale sarebbe il modo più performante?
- quale metodo sarebbe il più leggibile/manutenibile?
Aggiornamento: Complimenti per Matthew su suggerimento HTML Agility pacchetto. Ha funzionato bene! Anche il suggerimento XPath funziona. Vorrei poter contrassegnare entrambe le risposte come "La risposta", ma ovviamente non posso. Sono entrambe valide soluzioni al problema.
Ecco un'app per console C# che utilizza la regex suggerita da Jeff. Legge bene la stringa e non include alcun href che non è terminato con .txt. Con l'esempio fornito, NON include correttamente il file .txt.snarg
nei risultati (come previsto nella funzione di stringa HTML).
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
namespace ParsePageLinks
{
class Program
{
static void Main(string[] args)
{
GetAllLinksFromStringByRegex();
}
static List<string> GetAllLinksFromStringByRegex()
{
string myHtmlString = BuildHtmlString();
string txtFileExp = "href=\"([^\\\"]*\\.txt)\"";
List<string> foundTextFiles = new List<string>();
MatchCollection textFileLinkMatches = Regex.Matches(myHtmlString, txtFileExp, RegexOptions.IgnoreCase);
foreach (Match m in textFileLinkMatches)
{
foundTextFiles.Add(m.Groups[1].ToString()); // this is your captured group
}
return files;
}
static string BuildHtmlString()
{
return new StringReader(@"<html><head><title>Blah</title></head><body><br/>
<div>Here is your first text file: <a href=""http://myServer.com/blah.txt""></div>
<span>Here is your second text file: <a href=""http://myServer.com/blarg2.txt""></span>
<div>Here is your third text file: <a href=""http://myServer.com/bat.txt.snarg""></div>
<div>Here is your fourth text file: <a href=""http://myServer.com/somefile.txt""></div>
<div>Thanks for visiting!</div></body></html>").ReadToEnd();
}
}
}
Sei aperto all'utilizzo di un parser HTML Open Source? – Jeff
@JD: assolutamente! Come suggerito da Matthew, l'HTML Agility Pack sembra degno di uno sguardo. Stavi per suggerire questo o quello? –
@Philoushka Stavo per suggerire HTML Agility Pack ... si scatena. – Jeff