C# - Proste parsowane html?

0

Witam serdecznie!

W grudniu napisałem sobie z pomocą Google kod, który ze strony:
http://www.tibia.com/community/?subtopic=worlds&world=Menera
Pobiera nicki, levele, oraz profesje i najpierw wrzuca je do listboxa a następnie zapisuje je do pliku txt.
Gdy pisałem ten kod, to wszystko działało ok. Dziś kolega poprosił mnie abym dał mu ten program, ponieważ chce sobie spisać nicki wszystkich postaci online. To ok, odpalam projekt, kompiluje, a następnie uruchamiam. I Co się okazuje? Program przestał dodawać nicki do listboxa. Po debugowaniu programu nie ma żadnych błędów, po prostu po kliknięciu w button nic się nie dzieje. Możliwe ze coś się usunęło w kodzie, albo parsowanie jest źle wykonane, gdyż robiłem to tak bardziej na pamięć.

Oto kod mojej Class'y:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;
using System.Web;
using System.IO;
 
namespace ClassLibrary1
{
 
    public partial class Website
    {
        public delegate void WhoIsOnlineReceived(List<CharOnline> chars);
 
        public static string GetHTML(IAsyncResult ar)
        {
            HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);
            Stream respStream = response.GetResponseStream();
            string respBody = string.Empty;
            byte[] buf = new byte[8192];
            int count = 0;
            do
            {
                count = respStream.Read(buf, 0, buf.Length);
                if (count != 0)
                    respBody += Encoding.ASCII.GetString(buf, 0, count);
            }
            while (count > 0);
            return respBody;
        }
 
        public static string Prepare(string text)
        {
 
            return System.Web.HttpUtility.HtmlDecode(text) // Decode html character entities
                .Replace((char)0xA0, ' '); // Replace non-breaking spaces
        }
 
        public static void WhoIsOnline(string worldName, WhoIsOnlineReceived callback)
        {
            string url = "http://www.tibia.com/community/?subtopic=worlds&world=" + worldName;
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
 
 
            request.BeginGetResponse(delegate(IAsyncResult ar)
            {
                string html = GetHTML(ar);
 
 
                MatchCollection matches = Regex.Matches(html, @"<TD WIDTH=70%><[^<]*>([^<]*)</A></TD><TD WIDTH=10%>([^<]*)</TD><TD WIDTH=20%>([^<]*)</TD></TR>");
                List<CharOnline> chars = new List<CharOnline>(matches.Count);
                CharOnline co;
 
 
                for (int i = 0; i < matches.Count; i++)
                {
                    co = new CharOnline();
                    co.Name = Prepare(matches[i].Groups[1].Value);
                    co.Level = int.Parse(matches[i].Groups[2].Value);
                    co.Vocation = Prepare(matches[i].Groups[3].Value);
                    chars.Add(co);
                }
 
 
                callback(chars);
            }, request);
        }
 
 
        public class CharOnline
        {
            public string Name;
            public int Level;
            public string Vocation;
        }
    }
}

A to, główny kod programu:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private Boolean isSelected(string searchString)
        {
            for (int i = 0; i < this.listBox2.SelectedItems.Count; i++)
            {
                if (listBox2.SelectedItems[i].ToString() == searchString)
                {
                    return true;
                }
            }
            return false;
 
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            ClassLibrary1.Website.WhoIsOnline(comboBox1.Text, delegate(List<ClassLibrary1.Website.CharOnline> i)
           {
               listBox1.Invoke(new EventHandler(delegate
                {
                    for (int z = 0; z < i.Count(); z++)
                    {
                        if (comboBox2.Text == "Większy niż:")
                        {
                            if (i[z].Level > Int32.Parse(textBox2.Text) && isSelected(i[z].Vocation))
                            {
                                listBox1.Items.Add(i[z].Nick);
                            }
 
                        }
                    }
                    richTextBox1.Text = richTextBox1.Text + "[" + DateTime.Now.ToString() + "] Znaleziono " + listBox1.Items.Count + " Graczy. Obecnie jest " + i.Count() + " Graczy online.\r\n";
                }));
           });
        }
    }
}

ComboBox2 zawiera w sobie tekst: 'Większy niż:'
textBox2 zawiera w moim przypadku liczbę '1'
listBox2.SelectedItems wybrałem świat Menera.

A tak wygląda kod strony, którą chce sparsować:

<td style="width:70%;text-align:left;">
 <a name="A"/>
 <a href="http://www.tibia.com/community/?subtopic=characters&name=Aanjo">Aanjo</a>
 </td>
 <td style="width:10%;">170</td>
 <td style="width:20%;">Elder Druid</td>
 </tr>

Oczywiście te dane jak: Aanjo, 170, Elder Druid musi pobierać osobno, dla każdej z tabelek.
I nie mam pojęcia, czemu po kliknięciu w button, nie chce pobierać tych nicków ;/

Proszę o pomoc ;)

0

Gdy pisałem ten kod, to wszystko działało ok

To tak zwany “bit rot”, czyli „rdzewienie bitów”. Stare, wyciągnięte skądś programy mają tendencję do już nie działania.

po kliknięciu w button nic się nie dzieje
a wykonuje się w ogóle procedura obsługi zdarzenia? może „zapomniało” ci która procka ma się wykonywać w Clicked buttona.

0

Raczej mi się nie zapomniało, ponieważ kod znalazłem kiedyś na TibiaAPI - był on w tej bibliotece.
Przerobiłem go sobie kiedyś do pobierania ze źródła strony, linków do piosenek z playlisty wrzuty.pl.
Obecnie do pobierania i tworzenia linków używam tego kodu:

        private void button1_Click(object sender, EventArgs e)
        {
            List<string> linkList = new List<string>();
            string url = textBox1.Text;
            string sourceCode = WorkerClass.getSourceCode(url);
            int startIndex = sourceCode.IndexOf("[SND]");
            sourceCode = sourceCode.Substring(startIndex, sourceCode.Length - startIndex);
            while (sourceCode.IndexOf("<A HREF=") != -1)
          {
            startIndex = sourceCode.IndexOf("<A HREF=") + 9;
                int endIndex = sourceCode.IndexOf(".mp3", startIndex);

                string link = sourceCode.Substring(startIndex, endIndex - startIndex) + ".mp3";
                string fulllink = url + link;
                linkList.Add(fulllink);
                sourceCode = sourceCode.Replace("<A HREF=" + @"""" + link, "");
                
                           
         }

            foreach (string links in linkList)
            {
            listBox1.Items.Add(links);
            }
            }
    }
}

A kod strony wygląda tak:

<HR>
<IMG SRC="/icons/back.gif" ALT="[DIR]"> <A HREF="/up/nota/">Parent Directory</A>        22-Jan-2011 20:22      -  
<IMG SRC="/icons/sound2.gif" ALT="[SND]"> <A HREF="04%20Waiting%20Line.mp3">04 Waiting Line.mp3</A>     22-Jan-2011 19:17   3.1M  
<IMG SRC="/icons/sound2.gif" ALT="[SND]"> <A HREF="07%20The%20Remedy.mp3">07 The Remedy.mp3</A>       22-Jan-2011 19:15   1.4M  
<IMG SRC="/icons/sound2.gif" ALT="[SND]"> <A HREF="4ever.mp3">4ever.mp3</A>               22-Jan-2011 19:17   3.0M  
<IMG SRC="/icons/sound2.gif" ALT="[SND]"> <A HREF="A%20Whole%20New%20World.mp3">A Whole New World.mp3</A>   22-Jan-2011 19:17   1.1M  
<IMG SRC="/icons/sound2.gif" ALT="[SND]"> <A HREF="Are%20You%20Happy%20Now.mp3">Are You Happy Now.mp3</A>   22-Jan-2011 19:17   3.3M  

I to mi działa idealne, gdyż dostaje w listboxie eleganckie linki typu:
http://www.xxx.pl/music/4ever.mp3
itd...

Użyłem tamtego kodu ponieważ za cholerę nie mam pojęcia jak przerobić powyższy kod pod taką stronę:

<tr class="Odd" style="text-align:right;">
<td style="width:70%;text-align:left;">
<a name="A"/>
<a href="http://www.tibia.com/community/?subtopic=characters&name=Aarto+Sair">Aarto Sair</a>
</td>
<td style="width:10%;">84</td>
<td style="width:20%;">Knight</td>
</tr>
<tr class="Even" style="text-align:right;">
<td style="width:70%;text-align:left;">
<a href="http://www.tibia.com/community/?subtopic=characters&name=Ab+Aeterno">Ab Aeterno</a>
</td>
<td style="width:10%;">64</td>
<td style="width:20%;">Knight</td>
</tr>
<tr class="Odd" style="text-align:right;">
<td style="width:70%;text-align:left;">
<a href="http://www.tibia.com/community/?subtopic=characters&name=Abreu+of+menera">Abreu of menera</a>
</td>
<td style="width:10%;">179</td>
<td style="width:20%;">Knight</td>
</tr>

Może masz rozwiązanie, które by mi pomogło lub widzisz jakiś błąd?
Z góry dziękuje ;d

1 użytkowników online, w tym zalogowanych: 0, gości: 1