Fick en förfrågan på twitter om att skriva lite om vad som driver Senatåg.se och vår indexeringsmotor GovCrawler,så jag tänkte jag kan passa på nu när jag har några minuter ledigt över nyårshelgen och beskriva hur det funkar lite i detalj.
Många journalister jag pratat med har frågat hur jag egentligen ”får in alla tågen i datat”typ
Jag har försökt svara någorlunda enkelt,men jag har inte sett det kommit med i så många artiklar. Kanske har det ändå blivit för komplicerad förklaring. Nåja,nu tänkte jag göra det extremt komplicerat,så det här är nog bara för de som har intresse av utveckling.
Grunderna
Senatåg.se och GovCrawler är byggda helt på Microsofts ”.NET-Stack”. Programmeringspråket är .NET 4.0 (ASP.NET och C#). Indexeringsmotorn körs på en Windows 7 maskin,och webbplatsen hostas på en Windows Server maskin med IIS7. Kommunikation med databasen,som ligger på en SQL Server,görs med hjälp av LINQ till Entity Framework. Jag har gjort vissa försök att köra databasen på MySQL istället för SQL Server av kostnadskäl,men det har inte funkat så bra som jag vill så tills vidare gäller SQL Server. I GovCrawler används även en NoSQL-databas vid namn Db4objects för att lagra en del data lokalt.
Under hösten har jag byggt om stora delar av webbplatsen för att den ska bli snabbare och mer lättanvänd. Med tanke på det ökade besökarantalet så måste jag ha gjort något rätt
men man blir aldrig helt nöjd. Webbplatsen är som sagt byggd med ASP.NET,till större delen med WebForms just nu men tanken är att den framöver ska använda sig av ASP.NET MVC (när v3 är redo för produktion). Det mesta av gränssnittet använder sig av jQuery och jQuery UI,med diverse plugins,och kommunikation med servern vid sökningar m.m sker med AJAX-anrop och json-objekt. Vi använder också jTemplates flitigt.
Databasen
Databasen är inte så märkvärdig i sig,det är en ”vanlig”relationsdatabas med ett antal tabeller för statistik,stationer,företag,tåg m.m. Det som kräver mest jobb är egentligen att få in allt data på rätt sätt,det kommer från flera olika källor och måste tvättas och putsas innan det läggs in. Ett ständigt work in progress kan vi väl säga,även om det för det mesta är ganska stabilt. Databasen växer ganska mycket varje dag,just nu med mellan ca 10 000 och 20 000 rader per dag (mindre på helgerna då det körs färre tåg). Det är ju ingen facebook eller twitter men ganska spännande datamängder blir det!
Mina webbplatser hostas hos webbhosten Binero,som trots en del downtime,ssh-problem,och buggar i sin dashboard (den gillade verkligen inte IDN domäner,med t ex åäö,men det fixades nu i december) på det hela taget har varit en ganska stabil host. Villkoren är generösa tycker jag,och när man kör .NET 4.0 slipper man till och med det fruktade Medium Trust. Deras support har också varit väldigt tålmodig trots mina många klagomål
GovCrawler
Det var då webbdelarna,men hur är det med indexeringsmotorn? Jag kallar den då för ”GovCrawler”,som i ”Myndighetsskrapare”ungefär. Den är inne på 4:e generationen (de tidigare hette andra saker,men viss kod har följt med) och ett antal versioner,och namnet är lite inspirerat från OpenGov-rörelsen som jag är väldigt fascinerad av. Jag har länge varit intresserad av öppna myndigheter och offentlighetsprincipen,och det var faktiskt efter fruktlösa försök att få Trafikverket att lämna ut det data som finns här på Senatåg.se som jag byggde GovCrawler. Det får däremot bli en egen bloggpost.
GovCrawler fungerar i grunden som en automatiserad webbläsare,den läser vissa webbsidor på en viss webbadress (främst hos banverket.se just nu) och sparar ner dessa på hårddisken. Sen läser den igenom sidorna efter intressant information,i det här fallet efter försenade och inställda tåg. Den är modulärt uppbygd,så det är relativt enkelt att lägga till moduler som hämtar information från andra myndigheter eller liknande,men i dagsläget så läser den främst information från Trafikverket. Efter att sidorna är hämtade så läses de som sagt in i en lokal databas,och den försöker sedan lagra datat även i databasen på nätet genom ett API. De intressantaste sidorna är de sidor som visar hela sträckan för ett visst tåg,med information om varje station,men även stationsinformationssidorna är bra att ha. Vi lagrar det mesta.
Tågen
Det var den förenklade versionen kan man säga,i realiteten är det lite svårare än så. Till exempel så vet man inte riktigt vilka tåg man ska hämta,det finns nämligen ingen öppen tidtabell där alla tåg visas. Eller rättare sagt,det finns en del men de är inte så exakta kan man säga,och kan variera över dagen. Bland annat finns Trafikverkets Tågplan,som sällan stämmer överens helt med verkligheten då tågoperatörerna gör egna ändringar efter den är spikad,och en del andra dokument från TrV med olika grader av detaljrikedom. För att veta vilka tåg som ska hämtas så använder vi oss därför av flera olika källor,dels tittar vi på Tågplanen för att få en överblick,sen tittar vi på vilka tåg som gick samma dag för en vecka sedan (om det var en normal dag,inte över t ex julhelgen) samt läser stationssidorna för dagen och ser vilka tåg som körs då (fast där visas inte alla). Vi läser in tågsidorna några dagar i efterhand för att vara säkra på att få med all information även vid långa förseningar,så det är viss fördröjning. När det som nu är många tåg som är osäkra tittar vi dessutom även runt lite efter nyinsatta tåg som normalt inte skulle ha gått. När en tidtabell är helt ny tittar vi runt extra mycket för att vara säkra på att få med alla tåg,och för att bygga upp vår lista på tåg som går.
Just nu bygger jag om GovCrawler lite för att kunna visa lite mer aktuell information,men fokus ligger fortfarande på historiska förseningar. Trafikverket plockar bort sina tågsidor efter 2-3 dagar,så det gäller att hinna läsa alla ca 3000 sidorna innan det är försent (och utan att banka på servrarna onödigt mycket). Det ställer alltså höga krav på uptime,indexeringen får inte ligga nere någon längre tid (läs:max några timmar). Som tur var kan man köra den från flera olika datorer på olika nät utifall någon av dem skulle gå ner.
Inläsning
Sedan kommer analysfasen,där använder vi oss av det utmärkta HtmlAgilityPack för att skrapa sidorna på ett enkelt sätt. När vi har plockat ut datat måste det skrubbas,vilket sker med ett antal regular expressions och många många specialfall. Det är ingen rolig process,och kommer mycket från att det data som TrV visar upp ofta är bristfälligt,inte är konsekvent,och ibland helt saknas. Jag hoppas bara att deras interna system innehåller bättre data..
Hursomhelst,det är här magin händer kan man säga,det kräver en hel del tid och lite erfarenhet att få det rätt,och ibland blir det ändå fel. Vi kör därför stora batchuppdateringar,som fixar fel i det sparade datat genom att indexera om datat med bättre algoritmer,lite då och då.
Efter allt detta så behöver vi bara spara datat i databasen,så det blir sökbart på Senatåg.se. Om du undrar hur datat ser ut så kan du titta in på vårt API. Det är visserligen lite wrappat,i.e vi skippar att visa en del data som inte är intressant och lägger till annat,men ger ändå en bra ide på hur vår interna strukturer är uppbyggda.
Om något fortfarande är oklart eller du vill ha fler detaljer så ställ gärna frågor i kommentarerna.
Senaste kommentarerna