login到网站,通过C#

我对使用C#相对来说比较新,并且有一个应用程序可以读取网站上的部分源代码。 这一切都有效; 但问题是,有问题的页面需要用户login才能访问此源代码。 我的程序需要一种最初将用户login到网站的方式 – 完成之后,我将能够访问并阅读源代码。

需要login的网站是:mmoinn.com/index.do?PageModule=UsersLogin

我已经search了整整一天如何做到这一点,尝试过的例子,但没有运气。

提前致谢

您可以继续使用WebClient进行POST(而不是GET,这是您当前使用DownloadString的HTTP动词 ),但是我认为您会发现使用稍微低级的WebRequest和WebResponse更容易。

有两个部分 – 第一个是发布login表单,第二个是恢复“Set-cookie”标题,并将其作为“Cookie”发送回服务器以及GET请求。 服务器将使用这个cookie从现在开始识别你(假设它使用基于cookie的authentication,我相当确信这是因为该页面返回一个包含“PHPSESSID”的Set-cookie头)。


张贴到login表单

表单post很容易模拟,这只是一个格式化您的发布数据的情况下,如下所示:

field1=value1&field2=value2 

使用WebRequest和我从Scott Hanselman改编的代码,以下是如何将表单数据POST到您的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"]; 

以下是您应该在login表单的Set-cookie标题中看到的示例:

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

获取login表单后面的页面

现在,您可以对您需要login的页面执行GET请求。

 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(); } 

编辑:

如果您需要查看第一次POST的结果,则可以恢复返回的HTML:

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

直接放在cookieHeader = resp.Headers["Set-cookie"]; 然后检查pageSource中保存的string。

通过创build一个派生自WebClient的类,覆盖它的GetWebRequest方法并在其上设置一个CookieContainer对象,可以简化很多事情。 如果您始终设置相同的CookieContainer实例,则会自动为您处理Cookiepipe理。

但在发送之前获取HttpWebRequest的唯一方法是从WebClientinheritance并重写该方法。

 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"); 

马修布林德利 ,你的代码工作非常好,我需要一些网站(与login),但我需要改变HttpWebRequestHttpWebResponse否则我得到一个404错误的请求从远程服务器。 此外,我想分享我的解决方法,使用您的代码,是我试图login到基于 Moodle的 网站 ,但它没有工作在你的步骤“ 获取页面后面的login表单 ”,因为当成功发布后login,尽pipe其他网站的标题'Set-Cookie'没有返回任何东西。

所以我想这是我们需要为下一个请求存储cookie的地方,所以我添加了这个。

到“ 发送到login表单 ”代码块:

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

和“ 获取login表单后面的页面 ”:

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

这样做,让我login,并获得“页面后面login”(基于网站的moodle)的源代码我知道这是CookieContainer和HTTPCookies的模糊使用,因为我们可能会首先问是否有一个以前保存的cookie在发送请求到服务器之前。 这工作没有问题无论如何,但这里有一个很好的信息阅读有关示例项目和教程的WebRequestWebResponse
在.NET中检索HTTP内容
如何在.NET中使用HttpWebRequest和HttpWebResponse

您可以随时使用Watinnetworkingtesting框架。

有时,它可能有助于closuresAllowAutoRedirect并将同一用户代理设置为同时loginPOST和页面GET请求。

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