W większości opieram się na klasie, którą sam rozwijam, podstawową wersję znajdziesz tu: http://4programmers.net/Forum/522018?h=#id522018
A taką, która jest dostosowana do konkretnego projektu to np.:
public class Polaczenie
{
HttpWebRequest strona = null;
public CookieContainer cookies = new CookieContainer();
private string connParam = "Connection: keep-alive";
private string uagentParam = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4";
string host;
public Polaczenie(string host)
{
this.host = host;
}
public StreamReader SendPost(String addres, String PostValues){
strona = (HttpWebRequest)WebRequest.Create(addres);
strona.KeepAlive=true;
strona.Method = WebRequestMethods.Http.Post;
strona.ContentType = "application/x-www-form-urlencoded";
strona.ContentLength = PostValues.Length+connParam.Length+uagentParam.Length+6;
strona.CookieContainer= cookies;
StreamWriter requestStream = new StreamWriter(strona.GetRequestStream());
try{
requestStream.WriteLine(PostValues);
requestStream.WriteLine(uagentParam);
requestStream.WriteLine(connParam);
requestStream.Flush();
}catch(Exception ex){
Console.WriteLine(ex);
}
try{
HttpWebResponse odpowiedz = (HttpWebResponse)strona.GetResponse();
ResetCookies(odpowiedz.Cookies);
StreamReader responseStream = new StreamReader(odpowiedz.GetResponseStream());
return responseStream;
}catch(Exception ex){
Console.WriteLine(ex);
return null;
}
}
private string autousername = "deleted";
private string autopassword = "deleted";
public string phpsessid = "deleted";
private void ResetCookies(CookieCollection cc){
foreach(Cookie c in cc){
if(c.Name == "autousername"){
if(c.Value == "deleted"){
c.Value = autousername;
}else{
autousername = c.Value;
}
}
if(c.Name == "autopassword"){
if(c.Value == "deleted"){
c.Value = autopassword;
}else{
autopassword = c.Value;
}
}
if(c.Name == "PHPSESSID"){
if(c.Value == "deleted"){
c.Value = phpsessid;
}else{
phpsessid = c.Value;
}
}
//Console.WriteLine(c.Name+"="+c.Value);
}
cookies.Add(new Uri("http://"+host), new Cookie("autousername", autousername));
cookies.Add(new Uri("http://"+host), new Cookie("autopassword", autopassword));
}
public bool IsLoggedIn(){
return autousername!="deleted"&&autopassword!="deleted";
}
public StreamReader SendGet(string addres){
strona = (HttpWebRequest)WebRequest.Create(addres);
strona.KeepAlive=true;
strona.Method = WebRequestMethods.Http.Get;
//strona.ContentType = "application/x-www-form-urlencoded";
strona.CookieContainer = cookies;
try{
HttpWebResponse odpowiedz = (HttpWebResponse)strona.GetResponse();
ResetCookies(odpowiedz.Cookies);
StreamReader responseStream = new StreamReader(odpowiedz.GetResponseStream());
return responseStream;
}catch(Exception ex){
Console.WriteLine(ex);
return null;
}
}
}
Kiedyś gdzieś znalazłem prostą funkcję i teraz ją zwyczajnie rozwijam, co do botów, to po użyciu SendPost() Musisz wywołać funkcję Close, albo wykorzystać strumień, gdy zapomnisz o Close, to program się zawiesi. Najczęściej bedziesz wywoływał ją w sposób:
SendPost(url, postvalues).Close();
albo
SendPost(url, postvalues).ReadToEnd();
Jakiś tutorial: Szukaj na stronach powtarzających się fragmentów i na nich opieraj swoje wyrażenia regularne.
Np. Linki
runner.php?PA=113
runner.php?PA=123
runner.php?PA=513
to w wyrażeniu wykorzystaj fragment
runner.php?PA=
np. tak :
new Regex("runner\\.php\\?PA=\\d{1,6}")
Nie polecam stosowania kontrolki WebBrowser, bo choć to najprostsze rozwiązanie, to powoduje dodatkowe problemy, np. wyświetla popupy, albo odtwarza dźwięki.