Entre no site, via C #

Sou relativamente novo em usar o C # e tenho um aplicativo que lê partes do código-fonte em um site. Isso tudo funciona; mas o problema é que a página em questão requer que o usuário esteja logado para acessar este código-fonte. O que meu programa precisa para registrar inicialmente o usuário no site? Depois disso, eu conseguirei acessar e ler o código-fonte.

O site que precisa estar logado é: mmoinn.com/index.do?PageModule=UsersLogin

Eu procurei o dia inteiro sobre como fazer isso e tentei exemplos, mas não tive sorte.

desde já, obrigado

Você pode continuar usando o WebClient para POST (em vez de GET, que é o verbo HTTP que está usando com o DownloadString), mas acho que será mais fácil trabalhar com as classs (um pouco) de nível inferior WebRequest e WebResponse.

Há duas partes para isso – a primeira é postar o formulário de login, a segunda é recuperar o header “Set-cookie” e enviá-lo de volta ao servidor como “Cookie” junto com sua solicitação GET. O servidor usará esse cookie para identificá-lo a partir de agora (supondo que esteja usando a autenticação baseada em cookie, que estou bastante confiante de que é quando essa página retorna um header Set-cookie que inclui “PHPSESSID”).


Postando para o formulário de login

Postagens de formulário são fáceis de simular, é apenas um caso de formatar seus dados de postagem da seguinte maneira:

field1=value1&field2=value2 

Usando WebRequest e código que eu adaptei de Scott Hanselman , aqui está como você colocaria os dados do formulário POST em seu formulário de login:

 string formUrl = "http://www.mmoinn.com/index.do?PageModule=UsersAction&Action=UsersLogin"; // NOTE: This is the URL the form POSTs to, not the URL of the form (you can find this in the "action" attribute of the HTML's form tag string formParams = string.Format("email_address={0}&password={1}", "your email", "your password"); string cookieHeader; WebRequest req = WebRequest.Create(formUrl); req.ContentType = "application/x-www-form-urlencoded"; req.Method = "POST"; byte[] bytes = Encoding.ASCII.GetBytes(formParams); req.ContentLength = bytes.Length; using (Stream os = req.GetRequestStream()) { os.Write(bytes, 0, bytes.Length); } WebResponse resp = req.GetResponse(); cookieHeader = resp.Headers["Set-cookie"]; 

Veja um exemplo do que você deve ver no header Set-cookie do seu formulário de login:

 PHPSESSID=c4812cffcf2c45e0357a5a93c137642e; path=/; domain=.mmoinn.com,wowmine_referer=directenter; path=/; domain=.mmoinn.com,lang=en; path=/;domain=.mmoinn.com,adt_usertype=other,adt_host=- 

Obtendo a página por trás do formulário de login

Agora você pode executar sua solicitação GET para uma página na qual você precisa estar logado.

 string pageSource; string getUrl = "the url of the page behind the login"; WebRequest getRequest = WebRequest.Create(getUrl); getRequest.Headers.Add("Cookie", cookieHeader); WebResponse getResponse = getRequest.GetResponse(); using (StreamReader sr = new StreamReader(getResponse.GetResponseStream())) { pageSource = sr.ReadToEnd(); } 

EDITAR:

Se você precisar visualizar os resultados do primeiro POST, poderá recuperar o HTML retornado com:

 using (StreamReader sr = new StreamReader(resp.GetResponseStream())) { pageSource = sr.ReadToEnd(); } 

Coloque isso diretamente abaixo de cookieHeader = resp.Headers["Set-cookie"]; e, em seguida, inspecione a cadeia mantida em pageSource.

Você pode simplificar bastante as coisas criando uma class derivada do WebClient, substituindo o método GetWebRequest e definindo um object CookieContainer nele. Se você sempre definir a mesma instância de CookieContainer, o gerenciamento de cookies será tratado automaticamente para você.

Mas a única maneira de obter o HttpWebRequest antes de enviá-lo é herdar do WebClient e replace esse método.

 public class CookieAwareWebClient : WebClient { private CookieContainer cookie = new CookieContainer(); protected override WebRequest GetWebRequest(Uri address) { WebRequest request = base.GetWebRequest(address); if (request is HttpWebRequest) { (request as HttpWebRequest).CookieContainer = cookie; } return request; } } var client = new CookieAwareWebClient(); client.BaseAddress = @"https://www.site.com/any/base/url/"; var loginData = new NameValueCollection(); loginData.Add("login", "YourLogin"); loginData.Add("password", "YourPassword"); client.UploadValues("login.php", "POST", loginData); //Now you are logged in and can request pages string htmlSource = client.DownloadString("index.php"); 

Matthew Brindley , seu código funcionou muito bem para algum site que eu precisava (com login), mas eu precisava mudar para HttpWebRequest e HttpWebResponse caso contrário eu recebo um 404 Bad Request do servidor remoto. Também gostaria de compartilhar minha solução usando seu código, e é que tentei fazer login em um site baseado no moodle , mas não funcionou na sua etapa ” OBTENDO a página por trás do formulário de login ” porque quando POSTAR com êxito o login, o header 'Set-Cookie' não retornou nada, apesar de outros sites.

Então, acho que precisamos armazenar cookies para as próximas solicitações, então adicionei isso.

Para o bloco de código ” POSTING to the login form “:

 var cookies = new CookieContainer(); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl); req.CookieContainer = cookies; 

E para o ” Obtendo a página por trás do formulário de login “:

 HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl); getRequest.CookieContainer = new CookieContainer(); getRequest.CookieContainer.Add(resp.Cookies); getRequest.Headers.Add("Cookie", cookieHeader); 

Fazendo isso, deixa-me Logar-me e obter o código-fonte da “página de login” (site moodle) Eu sei que este é um uso vago do CookieContainer e HTTPCookies porque podemos perguntar primeiro há um conjunto previamente de cookies salvos antes de enviar o pedido para o servidor. Isso funciona sem problemas, mas aqui está uma boa informação para ler sobre WebRequest e WebResponse com exemplos de projetos e tutorial:
Recuperando conteúdo HTTP no .NET
Como usar o HttpWebRequest e o HttpWebResponse no .NET

Você sempre pode usar o framework de teste da web Watin .

Às vezes, isso pode ajudar a desativar o AllowAutoRedirect e definir as solicitações de login POST e de página GET o mesmo agente do usuário.

 request.UserAgent = userAgent; request.AllowAutoRedirect = false;