[PL] Pajączek na Wikipedię

W weekend wspomniałem wam o pewnej sympatycznej zabawie z wikipedią oraz o konkursie na aplikację, która by tę zabawę automatyzowała.

Póki co jeszcze nie otrzymałem od nikogo jakiegokolwiek rozwiązania, więc obniżę trochę poziom rozrywki, rozwiązuję za was problem wyciągania danych z Wikipedii.

Projekcik jest do pobrania tutaj: WikiPathFinding.zip

Nie jest doskonały, prawie w ogóle nie ma obsługi błędów, ale nie o to chodzi :)
Zawsze krok do przodu, więc.. jak będzie z samym algorytmem?

Jak ktoś nie chce pobierać projektu to wyciąganie danych z Wiki rozwiązałem poniższą, w parę minut napisaną klasą:

    public class WikiSpider
    {

        public string CoreUri = http://en.wikipedia.org;
        public string CoreTemplate = "/wiki/{keyword}";
        public string BannedWords = "Image:,Talk:,Special:,Main_Page,Portal:,Wikipedia:,Help:,#_ref";

        public List<string> GetLinks(string searchKey)
        {

           System.Net.WebClient http = new System.Net.WebClient();
           string htmlContent = "";

           try
            {
                htmlContent = http.DownloadString(CoreUri +
                    CoreTemplate.Replace("{keyword}",
searchKey.Replace(" ", "_")));
            }

            catch (System.Net.WebException webError)
            {
                //add some custom exception handling if you need.
                //here it's just a stub to handle it anyhow!
                return null;
            }

            List<string> keywords = new List<string>();
            Regex regex = new Regex("href=\"/wiki.*\".*title=\".*\"");

            Match m = regex.Match(htmlContent, 0, htmlContent.Length);
            keywords.Clear();

            do
            {
                bool add = true;

                string[] s = BannedWords.Split(",".ToCharArray());

                if (s.Length > 0)
                {
                    foreach (string ban in s)
                    {
                        if (m.Value.Contains(ban))
                            add = false;
                    }
                }

                if (add)
                {
            int startIdx, endIdx;
                    startIdx = m.Value.IndexOf("href=\"");
                    endIdx = m.Value.IndexOf("\"", startIdx+6);
                    string href = m.Value.Substring(startIdx+6,
endIdx - startIdx - 6);
                    startIdx = m.Value.IndexOf("title=\"", endIdx);
                    endIdx = m.Value.IndexOf("\"", startIdx + 7);
                    string title = m.Value.Substring(startIdx + 7,
                                   endIdx - startIdx - 7);
                    keywords.Add(href + "|" + title);

                }

                m = m.NextMatch();
                if (m.Value == "") m = null;

            } while (m != null);

            return keywords;

        }

    }

Jak wspomniałem, klasa niezbyt ładna, Regex nieperfekcyjny, ale działa. W projekcie dodatkowo prosty formularz, na którym można się zaczynać bawić w testowanie:

image
To ułatwienie wciąż nie kosztuje zmiany zasad w konkursie, aczkolwiek przy następnym to już będę musiał się solidnie zastanowić :)

Technorati Tagi: Polish Posts,coding,geeks