Soy relativamente nuevo en el uso de C # y tengo una aplicación que lee partes del código fuente en un sitio web. Que todo funciona; pero el problema es que la página en cuestión requiere que el usuario inicie sesión para acceder a este código fuente. Lo que mi programa necesita es una forma de iniciar la sesión del usuario en el sitio web; una vez hecho esto, podré acceder y leer el código fuente.
El sitio web que debe iniciar sesión es: mmoinn.com/index.do?PageModule=UsersLogin
He buscado durante todo el día cómo hacer esto y he probado ejemplos, pero no he tenido suerte.
Gracias por adelantado
c#
httpwebrequest
webclient
RyBolt
fuente
fuente
Respuestas:
Puede continuar usando WebClient para POST (en lugar de GET, que es el verbo HTTP que está usando actualmente con DownloadString), pero creo que le resultará más fácil trabajar con las clases WebRequest y WebResponse (ligeramente) de nivel inferior.
Hay dos partes para esto: la primera es publicar el formulario de inicio de sesión, la segunda es recuperar el encabezado "Set-cookie" y enviarlo de vuelta al servidor como "Cookie" junto con su solicitud GET. El servidor usará esta cookie para identificarlo de ahora en adelante (asumiendo que está usando autenticación basada en cookies, que estoy bastante seguro de que es porque esa página devuelve un encabezado Set-cookie que incluye "PHPSESSID").
PUBLICAR en el formulario de inicio de sesión
Las publicaciones de formulario son fáciles de simular, solo se trata de formatear los datos de la publicación de la siguiente manera:
Usando WebRequest y el código que adapté de Scott Hanselman , así es como enviaría los datos del formulario a su formulario de inicio de sesión:
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"];
Aquí hay un ejemplo de lo que debería ver en el encabezado Set-cookie para su formulario de inicio de sesión:
OBTENER la página detrás del formulario de inicio de sesión
Ahora puede realizar su solicitud GET en una página en la que debe iniciar sesión.
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:
Si necesita ver los resultados del primer POST, puede recuperar el HTML que devolvió con:
using (StreamReader sr = new StreamReader(resp.GetResponseStream())) { pageSource = sr.ReadToEnd(); }
Coloque esto directamente debajo
cookieHeader = resp.Headers["Set-cookie"];
y luego inspeccione la cadena contenida en pageSource.fuente
Puede simplificar un poco las cosas creando una clase que se derive de WebClient, anulando su método GetWebRequest y estableciendo un objeto CookieContainer en él. Si siempre configura la misma instancia de CookieContainer, la administración de cookies se manejará automáticamente por usted.
Pero la única forma de acceder a HttpWebRequest antes de que se envíe es heredar de WebClient y anular ese 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");
fuente
Matthew Brindley , su código funcionó muy bien para un sitio web que necesitaba (con inicio de sesión), pero necesitaba cambiar
HttpWebRequest
y, de loHttpWebResponse
contrario, recibo una solicitud incorrecta 404 del servidor remoto. También me gustaría compartir mi solución usando su código, y es que lo intenté para iniciar sesión en un sitio web basado en moodle , pero no funcionó en su paso " OBTENER la página detrás del formulario de inicio de sesión " porque al publicar correctamente el inicio de sesión, el encabezado'Set-Cookie'
no devolvió nada a pesar de que lo hacen otros sitios web.Creo que aquí es donde necesitamos almacenar cookies para las próximas solicitudes, así que agregué esto.
Al bloque de código " Enviar al formulario de inicio de sesión ":
var cookies = new CookieContainer(); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl); req.CookieContainer = cookies;
Y al " OBTENER la página detrás del formulario de inicio de sesión ":
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl); getRequest.CookieContainer = new CookieContainer(); getRequest.CookieContainer.Add(resp.Cookies); getRequest.Headers.Add("Cookie", cookieHeader);
Al hacer esto, me permite iniciar sesión y obtener el código fuente de la "página detrás del inicio de sesión" (moodle basado en el sitio web). Sé que este es un uso vago de las
CookieContainer
y HTTPCookies porque podemos preguntar primero si existe un conjunto de cookies previamente enviando la solicitud al servidor. De todos modos, esto funciona sin problemas, pero aquí hay una buena información para leerWebRequest
yWebResponse
con proyectos de muestra y tutorial:Recuperar contenido HTTP en .NET
Cómo usar HttpWebRequest y HttpWebResponse en .NET
fuente
A veces, puede ayudar a apagar
AllowAutoRedirect
y configurar tanto el inicio de sesiónPOST
como lasGET
solicitudes de página del mismo agente de usuario.request.UserAgent = userAgent; request.AllowAutoRedirect = false;
fuente