Вход На Веб-Сайт С Помощью C# Программно

Итак, я просматривал интернет, пытаясь узнать больше о том, как программно входить на веб-сайты с помощью 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 и смог собрать немного информации о том, какая информация отправляется на сервер, но я чувствую себя полностью потерянным. Если бы кто-нибудь мог пролить здесь свет, я был бы очень признателен.

2 ответов


вход в веб-сайты программно сложно и тесно связано с тем, как сайт реализует свою процедуру входа в систему. Причина, по которой ваш код не работает, заключается в том, что вы не имеете дело ни с чем из этого в своих запросах/ответах.

давайте возьмем fif.com например. При вводе имени пользователя и пароля отправляется следующий запрос post:

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

обратите внимание на куки (особенно первый, ваш токен сеанса). Обратите внимание на загадку 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 -это жонглирование куки и токенов и перенаправлений будет совершенно другим для другого сайта. По моему опыту (в частности, с этим сайтом) у вас есть три варианта, чтобы пройти через стену входа.

  1. написать невероятно сложный и хрупкий сценарий танцевать вокруг процедур сайта
  2. вручную войдите на сайт с помощью браузера, возьмите магические значения и подключите их к объектам запроса или
  3. создать скрипт для автоматизации селен сделать это для вас.

селен может обрабатывать все жонглирование, и в конце вы можете вытащить печенье и стрелять ваши запросы нормально. Вот пример для 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();

//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 для публикации (вместо GET, который the http-команду в настоящее время вы используете с DownloadString), но я думаю, вам будет легче работать с (немного) более низким уровнем классы WebRequest и WebResponse.

есть две части этого - первая-это разместить форму входа во-вторых, восстанавливает заголовок" Set-cookie " и отправляет его обратно сервер как "Cookie" вместе с вашим запросом GET. Сервер используйте этот файл cookie, чтобы идентифицировать вас с этого момента (предполагая, что он использует аутентификация на основе файлов cookie, в которой я уверен, что это так страница возвращает заголовок Set-cookie, который включает "PHPSESSID").


отправка в форму входа

форма сообщения легко имитировать, это просто случай форматирования вашего разместить данные следующим образом:

field1=value1&field2=value2

используя WebRequest и код, который я адаптировал из Скотт Хансельман, вот как вы отправляете данные формы в форму входа:

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

Примечание: это URL-адрес, по которому публикуется форма, а не URL-адрес формы (вы можете найти это в атрибуте "действие" тега формы HTML

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

вот пример того, что вы должны см. заголовок Set-cookie для ваша форма входа:

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

domain=.mmoinn.com, lang=en; path=/; domain=.mmoinn.com, adt_usertype=другое, 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();
}

EDIT:

Если вам нужно просмотреть результаты первого сообщения, Вы смогите взять HTML он вернулся с:

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

место это прямо под cookieHeader = resp.Headers["Set-cookie"]; а затем проверьте строку, удерживаемую в pageSource."