Logowanie do forum vbulletin + wyswietlanie najnowszych postów, odpowiadanie na nie etc.

0

Witam, postanowiłem napisać program - który jak w tytule ma wykonywać te funkcje plus jakieś tam dodatkowe. Jednak utknąłem niemalże na samym początku "pracy". Znalazłem w internecie kod który loguje się na forum - a mianowicie pobiera ciasteczko niezbędne do tego, jednak nie za bardzo wiem co z tym dalej zrobić, gdyż jak pobieram stronę przez webclient - to wyświetla błąd naruszenia pamięci, bądź nie loguje mnie. Czy vbulletin posiada jakiś webservice który umożliwiłby w przyjemny sposób korzystanie z jego funkcji? Oto tyle co mi się udało napisać (właściwie skopiować):

private void testLogowania()
        {
            WebClient client = new WebClient();
            string cookie = login("http://www.peb.pl/login.php?do=login", "uzytkownik", "haslo"); // include http and www (I don't have 10 forum posts)
            
            client.Headers.Add("Cookie", cookie);

            string testPobierania = client.DownloadString("http://www.peb.pl");
            if(client.IsBusy!=true)
            webBrowser1.DocumentText = testPobierania;
        }

        static string login(string url, string username, string password)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            string cookie = "";
            string values = "vb_login_username=" + username +
            "&vb_login_password=" + password +
            "&securitytoken=guest" +
            "&cookieuser=checked" +
            "&do=login";
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            req.ContentLength = values.Length;
            CookieContainer a = new CookieContainer();
            req.CookieContainer = a;

            System.Net.ServicePointManager.Expect100Continue = false; // prevents 417 error

            using (StreamWriter writer = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII)) { writer.Write(values); }

            HttpWebResponse c = (HttpWebResponse)req.GetResponse();
            foreach (Cookie cook in c.Cookies) { cookie = cookie + cook.ToString() + ";"; }

            return cookie;
        } 

Pozdrawiam.

0

Trzeba to po prostu zrobić jak należy. ;) Gdybyś używał proxy debugującego Fiddler2 albo chociaż dodatku do Firefox'a Tamper Data to byś zobaczył, że pod http://www.peb.pl jest 301 na http://peb.pl co niszczy Ci dane POST. Dodatkowo warto by się postarać o to, żeby żądanie imitowało przeglądarkę - czyli dodać odpowiednie nagłówki. No i jeszcze na koniec - dokonaj wyboru pomiędzy HttpWebRequest+HttpWebResponse a WebClient. ;)

 private void testLogowania()
        {
            WebClient client = new WebClient();
            string cookie = login("http://peb.pl/login.php?do=login", "xxx", "yyy"); // include http and www (I don't have 10 forum posts)
           
            client.Headers.Add("Cookie", cookie);
            client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10 (.NET CLR 3.5.30729)");
            client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
            client.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
            client.Headers.Add("Accept-Language", "pl,en-us;q=0.7,en;q=0.3");
            client.Headers.Add("Accept-Charset", "ISO-8859-2,UTF-8;q=0.7,*;q=0.7");
            client.Encoding = System.Text.Encoding.GetEncoding("ISO-8859-2");
            string testPobierania = client.DownloadString("http://peb.pl");

            if(client.IsBusy!=true) {}
            //webBrowser1.DocumentText = testPobierania;
        }

        static string login(string url, string username, string password)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
         
            req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10 (.NET CLR 3.5.30729)";
            req.ContentType = "application/x-www-form-urlencoded";
            req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            req.Headers.Add(HttpRequestHeader.AcceptLanguage, "pl,en-us;q=0.7,en;q=0.3");
            req.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-2,UTF-8;q=0.7,*;q=0.7");
            req.AllowAutoRedirect = false;

            string cookie = "";
            string values = "vb_login_username=" + username +
            "&vb_login_password=" + password +
            "&securitytoken=guest" +
            "&cookieuser=checked" +
            "&do=login";
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            req.ContentLength = values.Length;
            CookieContainer a = new CookieContainer();
            req.CookieContainer = a;

            System.Net.ServicePointManager.Expect100Continue = false; // prevents 417 error

            using (StreamWriter writer = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII)) { writer.Write(values); }

            HttpWebResponse c = (HttpWebResponse)req.GetResponse();
            foreach (Cookie cook in c.Cookies) { cookie = cookie + cook.ToString() + ";"; }

            return cookie;
        } 
0

Tak, z tym pewnie masz rację jednak wolałbym by było to możliwe za pomocą webservice, google nie zwróciło mi nic konkretnego, a dość nieprzyjemne będzie pisanie if-ów które uwzględnią wszelkie możliwe errory ^^ Ale jak to jedyne wyjście to wypada tak zrobić.

Mimo wszystko po kompilacji i zastosowaniu się do informacji z tej strony: http://www.csharp411.com/read-a-web-page-in-c/ dostaję błąd przy próbie odczytu strony w webrowser dostaję błędy skryptu - aż w końcu "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

0

No cóż, żeby napisać auto-postera lub innego typu bota zawsze trzeba się trochę pomęczyć. ;)
Zobacz sobie Klasa do pobierania danych HTTP - może się przyda.

Jeśli chodzi o WebBrowser to muszę niestety przyznać się, że w ogóle nie mam doświadczenia z tą kontrolką - nigdy nie było mi potrzebne jej używać. W którym miejscu dokładnie wywala błąd?

0

Heh, nie chcę żadnego bota, tylko aplikacja która powiadamia w tray-u o nowych postach, pm itp. :P No a wywala te dane podczas wczytywania wartości ze stringa do kontrolki webbrowser. Kiedy nie przekazuje tego stringa do webbrowsera to jest ok. Myślałem na początku że to spowodowane jest tym że nie zdążył pobrać jeszcze strony a ja chcę by wczytał ją - jednak jest to wg mnie nie możliwe bo postawiłem warunek

            if (client.IsBusy != true) { }
            webBrowser1.DocumentText = testPobierania; 

Więc teoretycznie nie powinno być problemu z tym związanego - spróbuję z innym forum może peb po prostu ma jakieś "funkcje" reklamowe przez które występują błędy.

//edit

Jednak na innych forach też się tak dzieje - wszędzie ten sam błąd.

0

Przeprowadziłem kilka testów i nie zauważyłem żadnych błędów związanych z pamięcią, wyskakują jedynie komunikaty o błędach JavaScript które można wyłączyć ustawiając właściwość WebBrowser.ScriptErrorsSuppressed na true. Co ciekawe błędy JS pojawiają się tylko jeśli załadujemy tekst do WebBrowser "ręcznie", podczas zwykłego nawigowania ich nie ma. Mogę zapytać w jakim celu używasz tej kontrolki?

0

W celu testów póki co. Może znajdzie swoje zastosowanie, w sumie program ma tylko służyć jako powiadamiacz więc pewnie później tego webbrowsera nie będzie. Ja ładuje ten tekst tak jak było w pierwotnej wersji. Zobaczę jak się ma sprawa na laptopie, bo może dzieje się tak z winy mojego komputera.

//Edit

Na laptopie działa wszystko ok. Nie wiem czym to może być spowodowane.

0

Kiedy spróbowałem użyć deserializacji by móc się logować na dane fora z danych kont, przestało mnie logować.

        private void testLogowania()
        {
            if (File.Exists("datavb.xml"))
            {
                XmlSerializer x = new XmlSerializer(typeof(List<ustawieniavb>));
                FileStream f = new FileStream("datavb.xml", FileMode.Open);
                List<ustawieniavb> sett = (List<ustawieniavb>)x.Deserialize(f);
                f.Close();

                MessageBox.Show(sett.ElementAt(0).url);
                MessageBox.Show(sett.ElementAt(0).login);
                MessageBox.Show(sett.ElementAt(0).password);

                WebClient client = new WebClient();
                string cookie = login(sett.ElementAt(0).url, sett.ElementAt(0).login ,sett.ElementAt(0).password); // include http and www (I don't have 10 forum posts)

                client.Headers.Add("Cookie", cookie);
                client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10 (.NET CLR 3.5.30729)");
                client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                client.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
                client.Headers.Add("Accept-Language", "pl,en-us;q=0.7,en;q=0.3");
                client.Headers.Add("Accept-Charset", "ISO-8859-2,UTF-8;q=0.7,*;q=0.7");
                client.Encoding = System.Text.Encoding.GetEncoding("ISO-8859-2");
                webBrowser1.ScriptErrorsSuppressed = true;
                string testPobierania = client.DownloadString(sett.ElementAt(0).url);

                if (client.IsBusy != true) 
                {
                    webBrowser1.DocumentText = testPobierania;
                }
                
            }
        }

Oto cookie które otrzymałem
cookie "bblastvisit=1291980512;bblastactivity=0;vbseo_loggedin=deleted;" string

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