2011-01-04 5 views
2

Ich probiere das HTML Agility Pack zum ersten Mal aus und verwende einen Beispielcode, um eine URL im HTML zu analysieren. Aber ich bekomme einen Fehler, von dem ich nicht weiß, warum ich ihn bekomme. Kann jemand auf mich hinweisen, was ich falsch mache?HTML Agility Pack-Fehler

Hier ist die Quelle (HTML ein eingehender HTML-String ist):

StringBuilder sb = new StringBuilder(); 

HtmlDocument htmldoc = new HtmlDocument(); 
htmldoc.LoadHtml(html); 

foreach (HtmlNode link in htmldoc.DocumentNode.SelectNodes("//a[@HREF]")) 
    { 
    HtmlAttribute att = link.Attributes["HREF"]; 
    sb.AppendLine(att.Value + "|"); 
    } 
return sb.ToString(); 

ich folgende Fehlermeldung erhalte, wenn ich meine app debuggen (Debugger es direkt nach dem "foreach" setzt):

System.NullReferenceException was unhandled 
    Message=Object reference not set to an instance of an object. 
    Source=ScreenScraper 
    StackTrace: 
     at ScreenScraper.its.GetITSLoadID(String html) in C:\Web_Projects\ScreenScaper\ScreenScraper\its.cs:line 22 
     at ScreenScraper.frm1.btnStartScraping_Click(Object sender, EventArgs e) in C:\Web_Projects\ScreenScaper\ScreenScraper\frm1.cs:line 43 
     at System.Windows.Forms.Control.OnClick(EventArgs e) 
     at System.Windows.Forms.Button.OnClick(EventArgs e) 
     at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 
     at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 
     at System.Windows.Forms.Control.WndProc(Message& m) 
     at System.Windows.Forms.ButtonBase.WndProc(Message& m) 
     at System.Windows.Forms.Button.WndProc(Message& m) 
     at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
     at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
     at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
     at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
     at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
     at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
     at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
     at System.Windows.Forms.Application.Run(Form mainForm) 
     at ScreenScraper.Program.Main() in C:\Web_Projects\ScreenScaper\ScreenScraper\Program.cs:line 18 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel) 
     at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly() 
     at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData) 
     at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext) 
     at System.Activator.CreateInstance(ActivationContext activationContext) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 
+0

Vielleicht gibt es ein Problem mit der Erstellung der Liste. Nur ein Vorschlag, aber versuchen Sie, die Liste der HtmlNodes vor der foreach zu initialisieren, und dann über die erstellte Liste zu iterieren. Wenigstens dann werden Sie in der Lage sein zu sehen, ob es die Schleife oder die Liste ist, die es verursacht – bakoyaro

Antwort

2

Das Html Agility Pack hat einen "Design-Fehler", der eine Null für eine leere Sammlung zurückgibt. So müssen Sie diese stattdessen tun:

HtmlNodeList list = htmldoc.DocumentNode.SelectNodes("//a[@HREF]"); 
if (list != null) 
{ 
    foreach (HtmlNode link in list) 
    ... 
} 

Und übrigens, alle Tags, die in dem XPath-Ausdruck angegeben werden, müssen klein geschrieben werden, auch wenn sie anders in dem HTML-Text deklariert ist (weil HTML Groß- und Kleinschreibung ist, Die Standard-XPATH-Konvention für das Html Agility Pack besteht darin, Kleinbuchstaben zu verwenden. Also sollten Sie dies stattdessen schreiben:

HtmlNodeList list = htmldoc.DocumentNode.SelectNodes("//a[@href]"); 
+0

Danke für das Wissen! Das hat perfekt funktioniert. – WildBill

+0

Eine Folgefrage dazu. Was wäre, wenn ich nach einem bestimmten "SelectNode" und nicht nach "SelectNodes" suche? Würde ich es immer noch in eine Liste aufnehmen und dann bewerten? – WildBill

+0

@Wildbill - SelectNode gibt null zurück, wenn nichts gefunden wurde (was mit den Standard-.NET-Regeln übereinstimmt) und andernfalls der ausgewählte Knoten –

Verwandte Themen