on Aug 19th, 2011Crawla en lista av adresser med “Microsoft.Web.Management.SEO.Crawler”
Jag fick i uppdrag att bygga en applikation som skulle kunna söka igenom hemsidor efter valideringsfel, punkter som inte följde generella standarder exempelvis ut en sökmotoroptimerings vinkel. Eftersom jag tidigare haft mycket erfarenhet av att använda mig av ett tillägg i IIS server vid namn “Microsoft SEO Toolkit”, så valde jag att bygga denna applikation kring det bibliotek som tillkommer när tillägget installeras. De kallar ramverket “Microsoft.Web.Management.SEO.Crawler” och har faktiskt många fördelar, men också många brister… Bara det faktum att Inga metoder är dokumenterade, så man får till viss det testa sig fram.
För att komma igång med biblioteket kan ni läsa en artikel som tar upp några av grunderna här: http://blogs.iis.net/carlosag/archive/2009/11/18/iis-seo-toolkit-start-new-analysis-automatically-through-code.aspx
Problemet med resultatet i den guiden är det faktum att i en MVC lösning så vill man inte att en webbsida skall stå still och ladda undertiden analysen genomförs. En laddnings-vy hade kanske varit en bättre ide, vilket är det jag kommer fokusera mig på i detta inlägg.
Hemligheten bakom denna lösning är baserad på en teknik som kallas “Threading” som tillåter dig att köra flera processer parallellt istället för att behöva vänta på att hela analysen är utförd. Till detta använder jag mig av Ajax för att hämta ut nuvarande status på det arbetande objektet samtidigt som den arbetar i en annan tråd.
Och nu till lite kod:
using System.Collections.Generic;
using System.Threading;
using Microsoft.Web.Management.SEO.Crawler;
using System.IO;
public class ListCrawler
{
public Guid Id { get; private set; }
public string DirectoryPath { get; set; }
public ProgressInformationDTO ProgressInformation { get; set; }
public string FullDirectoryPath
{
get
{
return (!SettingIsApplied || !ProgressInformation.IsComplete) ? "" : Path.Combine(DirectoryPath,Id.ToString());
}
}
public bool HasWorkingCrawler { get { return WorkingCrawler != null; } }
public bool WorkingCrawlerIsActive { get { return ProcessThread.IsAlive; } }
private WebCrawler WorkingCrawler { get; set; }
private List CrawlerList { get; set; }
private bool SettingIsApplied { get; set; }
private Thread ProcessThread { get; set; }
private CrawlerSettings Settings { get; set; }
public ListCrawler()
{
Settings = new CrawlerSettings();
CrawlerList = new List();
ProcessThread = new Thread(Execute);
SettingIsApplied = false;
Id = Guid.NewGuid();
}
public bool Start()
{
if (SettingIsApplied) ProcessThread.Start();
return SettingIsApplied;
}
public void Stop()
{
if (ProcessThread.IsAlive)
{
ProcessThread.Abort();
WorkingCrawler = null;
}
}
private void Execute()
{
ProgressInformation.TotalUrlCount = CrawlerList.Count;
ProgressInformation.UrlCounter = 0;
foreach (var item in CrawlerList)
{
ProgressInformation.UrlCounter++;
var dir = Path.Combine(DirectoryPath, Id.ToString());
Settings.StartUrl = item.Uri;
Settings.Name = ProgressInformation.UrlCounter.ToString();
item.Crawler = new WebCrawler(Settings);
WorkingCrawler = item.Crawler;
item.Crawler.Start();
ProgressInformation.CurrentUrl = item.Crawler.Settings.StartUrl.AbsoluteUri;
ProgressInformation.TotalBytesDownloaded += WorkingCrawler.BytesDownloaded;
while (item.Crawler.IsRunning)
{
ProgressInformation.TotalBytesDownloaded += WorkingCrawler.BytesDownloaded;
Thread.Sleep(500);
}
item.Crawler.Report.Save(dir);
}
ProgressInformation.IsComplete = true;
}
}
Vad är det då som händer här?
Detta är ett objekt som tillhandahåller en lista med adresser och “Crawler”-objekt som skall sökas igenom. Den har också en egenskap som är av typen “Thread” som jag kallar “ProgressThread” som instansieras i objektets konstruktor med metoden “Execute”. Det betyder att när tråden körs så kommer metoden “Execute” köras i den tråden ifrån rätt scope, vilket den gör när “Start”-metoden anropas.
I metoden “Execute” så händer en del saker men det som jag vill trycka på är att vi kan få “Thread”-objektet att sova utan att beröra resten av applikationen och det faktum att jag loopar igenom och analyserar alla objekt i listan.
Enkelt, eller hur?
Nästa vecka tar jag upp hur man kan göra för att hämta ut data från det körande objektet.
[...] RSS Feed « Crawla en lista av adresser med “Microsoft.Web.Management.SEO.Crawler” [...]