Ich habe einen kleinen Crawler gebaut und jetzt, als ich es ausprobiert habe, habe ich festgestellt, dass mein Crawler beim Crawlen bestimmter Sites 98-99% CPU verwendet.
Ich habe dotTrace
verwendet, dotTrace
zu sehen, was das Problem sein könnte, und es wies mich auf meine httpwebrequest
Methode hin - ich habe sie mit Hilfe einiger vorheriger Fragen hier auf stackoverflow etwas optimiert. Aber das Problem war immer noch da.
Ich ging dann, um zu sehen, welche URLs, die die CPU-Belastung verursacht und festgestellt, dass es tatsächlich Websites, die extrem groß sind - gehen Abbildung :) So, jetzt bin ich 99% sicher, es hat mit dem folgenden Stück Code zu tun:
HtmlAgilityPack.HtmlDocument documentt = new HtmlAgilityPack.HtmlDocument();
HtmlAgilityPack.HtmlNodeCollection list;
HtmlAgilityPack.HtmlNodeCollection frameList;
documentt.LoadHtml(_html);
list = documentt.DocumentNode.SelectNodes(".//a[@href]");
Alles, was ich tun möchte, ist, die Links auf der Seite zu extrahieren, also für große Sites. Gibt es da sowieso, dass ich das dazu bringen kann, nicht so viel CPU zu benutzen?
Ich dachte, vielleicht zu begrenzen, was ich hole? Was wäre meine beste Option hier?
Sicherlich muss jemand schon mal auf dieses Problem gestoßen sein :)
"./a[@href" ist extrem langsamer XPath. Versucht, mit "// a [@href]" zu ersetzen oder mit Code, der einfach das gesamte Dokument durchläuft und alle A-Knoten überprüft.
Warum ist dieser XPath langsam?
Abschnitt 1 + 2 endet mit "für jeden Knoten alle seine Nachkommenknoten auswählen", was sehr langsam ist.
Wenn Sie nicht stark in Html Agility Pack investiert sind, versuchen Sie stattdessen, CsQuery zu verwenden. Es erstellt einen Index beim Parsen der Dokumente und Selektoren sind viel schneller als HTML Agility Pack. Siehe einen Vergleich.
CsQuery ist ein .NET-jQuery-Port mit einer vollständigen CSS-Selektor-Engine. Sie können CSS-Selektoren sowie die jQuery-API verwenden, um auf HTML zuzugreifen und sie zu bearbeiten. Es ist auf nugget als CsQuery.