用C#编程登录网站

本文关键字:网站 登录 编程 | 更新日期: 2023-09-27 18:21:13

所以,我一直在网上搜索,试图了解更多关于如何使用C#以编程方式登录网站的信息。我不想使用网络客户端。我想我想使用HttpWebRequest和HttpWebResponse之类的东西,但我不知道这些类是如何工作的。

我想我正在找人解释他们是如何工作的,以及成功登录WordPress、电子邮件帐户或任何需要填写用户名和密码的网站所需的步骤。

这是我的一个尝试:

// Declare variables
        string url = textBoxGetSource.Text;
        string username = textBoxUsername.Text;
        string password = PasswordBoxPassword.Password;
        // Values for site login fields - username and password html ID's
        string loginUsernameID = textBoxUsernameID.Text;
        string loginPasswordID = textBoxPasswordID.Text;
        string loginSubmitID = textBoxSubmitID.Text;
        // Connection parameters
        string method = "POST";
        string contentType = @"application/x-www-form-urlencoded";
        string loginString = loginUsernameID + "=" + username + "&" + loginPasswordID + "=" + password + "&" + loginSubmitID;
        CookieContainer cookieJar = new CookieContainer();
        HttpWebRequest request;
        request = (HttpWebRequest)WebRequest.Create(url);
        request.CookieContainer = cookieJar;
        request.Method = method;
        request.ContentType = contentType;
        request.KeepAlive = true;
        using (Stream requestStream = request.GetRequestStream())
        using (StreamWriter writer = new StreamWriter(requestStream))
        {
            writer.Write(loginString, username, password);
        }
        using (var responseStream = request.GetResponse().GetResponseStream())
        using (var reader = new StreamReader(responseStream))
        {
            var result = reader.ReadToEnd();
            Console.WriteLine(result);
            richTextBoxSource.AppendText(result);
        }
        MessageBox.Show("Successfully logged in.");

我不知道我是否在正确的轨道上。我最终被返回到我尝试的任何网站的登录屏幕。我已经下载了Fiddler,并能够收集一些关于发送到服务器的信息,但我感到完全迷失了方向。如果有人能在这里透露一些信息,我将不胜感激。

用C#编程登录网站

用程序登录网站很困难,而且与网站如何实现登录过程密切相关。你的代码不起作用的原因是你在请求/响应中没有处理这些问题。

让我们以fif.com为例。当你输入用户名和密码时,会发送以下张贴请求:

POST https://fif.com/login?task=user.login HTTP/1.1
Host: fif.com
Connection: keep-alive
Content-Length: 114
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: https://fif.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.103 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: https://fif.com/login?return=...==
Accept-Encoding: gzip,deflate
Accept-Language: en-US,en;q=0.8
Cookie: 34f8f7f621b2b411508c0fd39b2adbb2=gnsbq7hcm3c02aa4sb11h5c87f171mh3; __utma=175527093.69718440.1410315941.1410315941.1410315941.1; __utmb=175527093.12.10.1410315941; __utmc=175527093; __utmz=175527093.1410315941.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmv=175527093.|1=RegisteredUsers=Yes=1
username=...&password=...&return=aHR0cHM6Ly9maWYuY29tLw%3D%3D&9a9bd5b68a7a9e5c3b06ccd9b946ebf9=1

注意cookie(尤其是第一个,您的会话令牌)。请注意正在发送的加密url编码的返回值。如果服务器发现这些内容丢失,它将不允许您登录。

HTTP/1.1 400 Bad Request

或者更糟的是,登录页面的200响应中隐藏了一条错误消息。

但让我们假设您能够收集所有这些神奇的值,并将它们传递到HttpWebRequest对象中。网站不会知道有什么区别。它可能会做出这样的回应。

HTTP/1.1 303 See other
Server: nginx
Date: Wed, 10 Sep 2014 02:29:09 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Location: https://fif.com/

希望你早就预料到了。但是,如果你已经做到了这一点,你现在可以用程序的方式用你现在验证过的会话令牌向服务器发送请求,并获得预期的HTML。

GET https://fif.com/ HTTP/1.1
Host: fif.com
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.103 Safari/537.36
Referer: https://fif.com/login?return=aHR0cHM6Ly9maWYuY29tLw==
Accept-Encoding: gzip,deflate
Accept-Language: en-US,en;q=0.8
Cookie: 34f8f7f621b2b411508c0fd39b2adbb2=gnsbq7hcm3c02aa4sb11h5c87f171mh3; __utma=175527093.69718440.1410315941.1410315941.1410315941.1; __utmb=175527093.12.10.1410315941; __utmc=175527093; __utmz=175527093.1410315941.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmv=175527093.|1=RegisteredUsers=Yes=1

这就是fif.com的全部内容——对于另一个网站来说,这种cookie、代币和重定向的杂耍将完全不同。根据我的经验(尤其是该网站),你有三个选项可以通过登录墙。

  1. 写一个极其复杂和脆弱的脚本,围绕网站的程序跳舞
  2. 使用浏览器手动登录网站,获取神奇的值,并将其插入您的请求对象或
  3. 创建一个脚本来自动执行selenium操作

Selenium可以处理所有的杂耍,最后你可以取出cookie并正常启动你的请求。下面是一个fif:的例子

//Run selenium
ChromeDriver cd = new ChromeDriver(@"chromedriver_win32");
cd.Url = @"https://fif.com/login";
cd.Navigate();
IWebElement e = cd.FindElementById("username");
e.SendKeys("...");
e = cd.FindElementById("password");
e.SendKeys("...");
e = cd.FindElementByXPath(@"//*[@id=""main""]/div/div/div[2]/table/tbody/tr/td[1]/div/form/fieldset/table/tbody/tr[6]/td/button");
e.Click();
CookieContainer cc = new CookieContainer();
//Get the cookies
foreach(OpenQA.Selenium.Cookie c in cd.Manage().Cookies.AllCookies)
{
    string name = c.Name;
    string value = c.Value;
    cc.Add(new System.Net.Cookie(name,value,c.Path,c.Domain));
}
//Fire off the request
HttpWebRequest hwr = (HttpWebRequest) HttpWebRequest.Create("https://fif.com/components/com_fif/tools/capacity/values/");
hwr.CookieContainer = cc;
hwr.Method = "POST";
hwr.ContentType = "application/x-www-form-urlencoded";
StreamWriter swr = new StreamWriter(hwr.GetRequestStream());
swr.Write("feeds=35");
swr.Close();
WebResponse wr = hwr.GetResponse();
string s = new System.IO.StreamReader(wr.GetResponseStream()).ReadToEnd();

查看这篇文章。这是另一种方法,您不需要安装任何软件包,尽管使用Selenium可能会更容易。

"您可以继续使用WebClient进行POST(而不是GET,即您当前与DownloadString一起使用的HTTP谓词),但是我我想你会发现用(稍微)低一点的级别工作更容易类WebRequest和WebResponse。

这有两个部分——第一部分是发布登录表单第二个是恢复"Set cookie"标头并将其发送回服务器作为"Cookie"与您的GET请求。服务器将从现在起使用此cookie来识别您(假设它正在使用基于cookie的身份验证,我很有信心页面返回一个Set cookie头,其中包括"PHPSESSID")。


张贴到登录表单

表单帖子很容易模拟,这只是格式化您的张贴数据如下:

field1=value1&field2=value2

使用WebRequest和我改编自Scott Hanselman的代码如何将表单数据张贴到登录表单:

string formUrl = "http://www.mmoinn.com/index.do?PageModule=UsersAction&Action=UsersLogin";

注意:这是表单张贴到的URL,而不是表单的URL(您可以在HTML的表单标签的"action"属性中找到这一点

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

以下是您应该在的Setcookie标头中看到的内容的示例您的登录表格:

PHPSESSID=c4812cffcf2c45e0357a5a93c137642e; path=/; domain=.mmoinn.com,wowmine_referer=directenter; path=/;

domain=.mmunn.com,lang=en;路径=/;domain=.mmunn.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();
}

编辑:

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

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

将其直接放置在cookieHeader = resp.Headers["Set-cookie"];下方然后检查pageSource中保存的字符串。"