söndag 8 juli 2007

Forts: Exportera "blogg" från Lunarstorm

Okej, jag kunde inte hålla mig, var tvungen att göra ett försök till implementation av Lunar-blogg-export. Såhär gick det till:

Jag kom ihåg att det finns en .NET-kontroll som heter WebBrowser som är en wrapper runt Internet Explorers motor och presentation. Bara att dra och släppa den på WinForm-designytan och man har ett browserfönster som kan navigera runt på webben. Smidigt.

Vad jag däremot inte kände till var att man programmatiskt kan komma åt det HTML-dokument som browsern laddat, komplett med DOM-träd och allt. Detta betyder att man exempelvis kan klättra sig fram till specifika noder och manipulera dem "live". Aha - jag kunde alltså låta browsern navigera till Lunarstorms startsida och (när den väl laddat) fylla i mina användaruppgifter samt "klicka" på Logga in-knappen helt automatiskt. Första hindret avklarat: att få programmet att logga in på Lunarstorm förklädd till mig själv.

Sedan då? Som jag nämnde i min förra post använder sig Lunarstormsajten av ett UserID vilket är en sträng med jox som identifierar mig som inloggad användare. Detta behöver man eftersom det är en komponent i vissa undersidors adresser, exempelvis den egna Lunarbloggens. Efter att ha studerat HTML-koden på sidan som dyker upp efter man har loggat in hittade jag ett ställe där UserID:et används i ett Javascriptblock. Bara att plocka ut med regular expressions. Andra hindret övervunnet: att hitta och hämta mitt eget UserID.

Nu kunde jag låta browsern navigera till Lunarbloggens huvudsida, där de 25 senaste blogginläggen visas. Måste ha PostID för varje inlägg (en sträng som identifierar varje inlägg) för att kunna gå till respektive inläggs egna sida. Borde bara vara att gå igenom alla länkar på listsidan och plocka ut PostID med en matchning men så enkelt var det inte!

Det visade sig att WebBrowser-kontrollen har lite svårt för att uppdatera sitt DOM-träd korrekt när en sida använder frames. Jag inspekterar DOM-trädet då eventet DocumentCompleted inträffar, alltså då browsern har laddat färdigt det aktuella dokumentet. Men detta träd innehåller aldrig noderna i de nestade iframe-elementen! Attans. Vad göra? Sova. Tänka. Och sedan: hämta en referens till det aktuella fönstret i browsern och stega igenom alla frames. Genom att titta efter huvudframens namn ("lunar_main", som det ser ut nu) kan programmet avgöra när rätt frame hittats.

En intressant insikt: även om man hittat rätt frame och plockat fram dess dokument (programmatiskt) så är inte dokumentets elementlistor uppdaterade. Exempelvis innehåller propertyn Links inte sina egna länkar, utan huvuddokumentets. Däremot funkar det fint att klättra i DOM-trädet och på det sättet hitta de noder man söker (exempelvis genom metoder som GetElementById() och GetElementsByName()).

Resultat: programmet kunde nu, med hjälp av några schyssta regular expression-matchningar, extrahera PostID för de 25 senaste blogginläggen. Sweet! Tredje hindret alltså besegrat.

Övriga listsidor var enkla: bara att låta programmet klicka sig fram och samla in PostID-information så länge det finns en "Nästa"-knapp på sidan. Plockade samtidigt titel och datum från listorna. Hade alltså nu en fullständig lista över alla blogginlägg. Dessutom snyggt sorterade i fallande ordning efter datum.

Nästa moment: att låta användaren välja vilka av de funna inläggen som ska exporteras. En smal sak. När användaren gjort sitt val går programmet igenom listan och laddar den sida som visar varje inläggs innehåll. Där kan texten läsas ut ganska lätt, eftersom Lunarcrew varit vänliga nog att sätta den i en tabellrad med ett vettigt ID.

Sista steget är att spara de inlästa inläggen till en XML-fil som validerar mot någon RSS-standard. Jag valde RSS 2.0.

Och slutresultatet? Ett nätt litet .NET 2.0-program, inte helt testat och inte garanterat stabilt, men det har funkat för mig. Du hittar det här: http://blogg.fjeldstad.se/2007/07/lunarbloggrabber-05_9761.html

1 kommentar:

  1. Jag vet inte om jag kommenterat att du är nördig. Jag är dock imponerad.

    SvaraRadera