C# 通过C登录到网站#

C# 通过C登录到网站#,c#,httpwebrequest,webclient,C#,Httpwebrequest,Webclient,我对使用C#比较陌生,有一个应用程序可以读取网站上的部分源代码。一切顺利;但问题是,有问题的页面需要用户登录才能访问此源代码。我的程序需要一种方法来让用户最初登录到网站——完成后,我将能够访问并阅读源代码 需要登录的网站是: mmoinn.com/index.do?PageModule=UsersLogin 我花了一整天的时间寻找如何做到这一点,并尝试了一些例子,但都没有成功 提前感谢您可以继续使用WebClient发布(而不是GET,这是您当前使用的DownloadString),但我认为您会

我对使用C#比较陌生,有一个应用程序可以读取网站上的部分源代码。一切顺利;但问题是,有问题的页面需要用户登录才能访问此源代码。我的程序需要一种方法来让用户最初登录到网站——完成后,我将能够访问并阅读源代码

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

我花了一整天的时间寻找如何做到这一点,并尝试了一些例子,但都没有成功


提前感谢

您可以继续使用WebClient发布(而不是GET,这是您当前使用的DownloadString),但我认为您会发现使用(稍微)较低级别的类WebRequest和WebResponse更容易

这有两部分-第一部分是发布登录表单,第二部分是恢复“Set cookie”头并将其作为“cookie”与GET请求一起发送回服务器。从现在起,服务器将使用这个cookie来识别您(假设它使用基于cookie的身份验证,我非常确信这是因为该页面返回一个包含“PHPSESSID”的集cookie头)


发布到登录表单

表单帖子很容易模拟,只是将帖子数据格式化如下:

field1=value1&field2=value2
使用WebRequest和我改编自的代码,以下是您将表单数据发布到登录表单的方式:

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"];
PHPSESSID=c4812cffcf2c45e0357a5a93c137642e; path=/; domain=.mmoinn.com,wowmine_referer=directenter; path=/; domain=.mmoinn.com,lang=en; path=/;domain=.mmoinn.com,adt_usertype=other,adt_host=-
以下是您应该在登录表单的Set cookie标头中看到的示例:

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"];
PHPSESSID=c4812cffcf2c45e0357a5a93c137642e; path=/; domain=.mmoinn.com,wowmine_referer=directenter; path=/; domain=.mmoinn.com,lang=en; path=/;domain=.mmoinn.com,adt_usertype=other,adt_host=-

获取登录表单后面的页面

现在,您可以对需要登录的页面执行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();
}
编辑:

如果需要查看第一篇文章的结果,可以恢复它返回的HTML:

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

将其直接放在
cookieHeader=resp.Headers[“设置cookie”]下面,然后检查pageSource中保存的字符串。

通过创建一个从WebClient派生的类,重写其GetWebRequest方法并在其上设置CookieContainer对象,可以大大简化工作。如果您总是设置相同的CookieContainer实例,那么cookie管理将自动为您处理

但是在发送HttpWebRequest之前获取它的唯一方法是从WebClient继承并重写该方法

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

有时,它可能有助于关闭
AllowAutoRedirect
,并设置登录
POST
和页面
GET
请求相同的用户代理

request.UserAgent = userAgent;
request.AllowAutoRedirect = false;
,您的代码在我需要的某些网站上运行得非常好(通过登录),但我需要更改为
HttpWebRequest
HttpWebResponse
,否则我会从远程服务器收到404错误请求。另外,我想与大家分享一下我使用您的代码的解决方法,我尝试使用它登录到一个基于moodle的网站,但在您的步骤“获取登录表单后面的页面””时,它不起作用,因为当成功发布登录时,尽管其他网站返回了任何内容,但标题
'Set-Cookie'
没有返回任何内容

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


到“发布到登录表单”代码块:

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

并转到“获取登录表单后面的页面”

HttpWebRequest getRequest=(HttpWebRequest)WebRequest.Create(getUrl);
getRequest.CookieContainer=新的CookieContainer();
getRequest.CookieContainer.Add(分别是Cookies);
添加(“Cookie”,cookieHeader);

这样做,让我登录并获取“页面隐藏登录”(基于网站的moodle)的源代码。我知道这是对
CookieContainer
和HttpCookie的模糊使用,因为我们可能会首先询问在将请求发送到服务器之前是否保存了以前的一组Cookie。不管怎么说,这都没有问题,但是这里有一个很好的信息,可以通过示例项目和教程阅读
WebRequest
WebResponse


因此,我可以想出很多方法来实现这一点。。。C#程序是通过HTTP直接从服务器请求“代码”,还是依赖浏览器应用程序?需要更多的信息。该程序使用WebClient.DownloadString(“URL”),非常感谢您的详细回复;但还有一部分我不确定。我是不是应该改变一些关于“Set-cookie”、“cookie”或者你发布的“PHPSESSID”的东西?我试着在一个程序中简单地使用该代码输入我的信息,但它似乎没有让我登录(我想我把cookies搞砸了)。该代码应该可以逐字使用。服务器设置cookie(在Set cookie中),客户端(即您)将cookie作为cookie发送回。要检查的第一件事是,第一篇帖子确实让您登录,您可能会发现服务器希望在表单帖子中出现另一个字段(听起来很奇怪,您有时需要一个带有按钮名称的空字段)。我已经更新了帖子,以显示如何查看帖子的结果。我不确定我第一次做错了什么,但现在它可以工作了!非常感谢你的帮助。我怎样才能确定用户是否成功通过身份验证?我知道我们不应该在这里写感谢,但是伙计,你救了我一命+1调试时,(公开)cookie始终为空。该网站肯定会在我下载的页面上发布cookies。谢谢,经过几个小时的寻找解决方案,这很有效!