C# で Web サイトにログインする
-
C#
でWebClient
を使用して Web サイトにログインする -
C#
で Web サイトにログインするスクリプトを作成する -
C#
でSelenium
を自動化して Web サイトにログインするスクリプトを作成する -
C#
でHttpClient
を使用して Web サイトにログインする
このチュートリアルでは、C# でプログラムによって Web サイトにログインするための最適化された方法を学び、理解します。 ASP.NET C# を使用して外部 Web サイトに自動ログインすることが可能です。Web サイトが HTTP POST
を使用してログインを検証する場合は、post
メソッドを外部で使用できます。
Visual Studio は proxy class web server
メソッドを呼び出して自動的にプロキシを生成するため、サービス参照を C# プロジェクトに追加するのが一般的な方法です。 ただし、プログラマティックは Web サーバーを呼び出して認証するための最適な方法です。
C#
で WebClient
を使用して Web サイトにログインする
ウェブサイトへのプログラムによるログインの最善の方法は、WebClient
を POST
に使用することです。 POST
(初心者レベルの開発者にとっては非常に複雑なため) の確実な代替は、下位レベルの WebRequest
および WebResponse
クラスです。
ログイン フォームの作成は、このアプローチの 2つの主要な部分の 1つであり、2つ目は、GET
リクエストを使用して Set-cookie
ヘッダーを回復することです。 GET
リクエストと一緒に送信した Cookie
としての Set-cookie
ヘッダーが、応答するサーバーによって認識された場合、サーバーが Cookie ベースの認証を使用している場合にのみ、それ以降はあなたを識別します。
GET
には次の C# コードを使用します。
public static string HttpGet(string web_URI) {
System.Net.WebRequest web_request = System.Net.WebRequest.Create(web_URI);
// the following means no proxy for the website
web_request.Proxy = new System.Net.WebProxy(ProxyString, true);
System.Net.WebResponse web_response = web_request.GetResponse();
System.IO.StreamReader stream_reader =
new System.IO.StreamReader(web_response.GetResponseStream());
return stream_reader.ReadToEnd().Trim();
}
SET
には次の C# コードを使用します。
public static string HttpPost(string web_URI, string web_para) {
System.Net.WebRequest web_request = System.Net.WebRequest.Create(web_URI);
web_request.Proxy = new System.Net.WebProxy(ProxyString, true);
// add the following as you are doing the `POST`
web_request.ContentType = "your_application/insert-the-form-rncoded-URL";
web_request.Method = "POST"; // SET
// it's important to know how many bytes you are transforming or sending to the server.
// Remember | Post'ed Faked Forms should be `name=value&`
byte[] sending_bytes = System.Text.Encoding.ASCII.GetBytes(web_para);
web_request.ContentLength = sending_bytes.Length;
System.IO.Stream web_stream = web_request.GetRequestStream();
// you can push the bytes here
web_stream.Write(sending_bytes, 0, sending_bytes.Length);
web_stream.Close();
System.Net.WebResponse web_response = web_request.GetResponse();
if (web_response == null)
return null;
System.IO.StreamReader stream_reader =
new System.IO.StreamReader(web_response.GetResponseStream());
return stream_reader.ReadToEnd().Trim();
}
次のような方法で投稿データを簡単にフォーマットできるため、フォーム投稿は簡単にシミュレートできます。
field_1 = value_1 & field_2 = value_2
このメソッドのサンプル C# WebClient
コードは、WebRequest
を使用して Web サイトにログインするための Scott Hanselman アプローチを反映しています。
さらに、次の C# コードは、プログラムで Web サイトにログインするために Scott Hanselman によって作成されたアプローチを表しています。
// the `web_URL` represents the `POST` URL instead of the `form` URL
// to access `form` URL, find the `action` attribute of the HTML's `form` tag
string web_URL =
"http://www.examplewebsite.com/index.do?PageModule=UserAccess&Modification=UsersVerificationviaLogin";
string parameter_form = string.Format("example_format(email_address={0}&password={1})",
"my_email_address", "my_password");
// create a header cookie
string header_cookie;
// create a request object from the `WebRequest`
WebRequest web_request = WebRequest.Create(web_URL);
// define its content type and method
web_request.ContentType =
"yourC#application/x-www_address-form-encoded_url"; // or something like
// "application/x-www-form-urlencoded"
web_request.Method = "POST"; // as it's a request, so the method will be POST
// access the `parameter_form` to convert it into bytes (sending it to the server)
byte[] sending_bytes = Encoding.ASCII.GetBytes(parameter_form);
web_request.ContentLength = sending_bytes.Length; // define its length
using (Stream web_stream = web_request.GetRequestStream()) {
// for web requests or requests to the server for login
web_stream.Write(sending_bytes, 0, sending_bytes.Length);
}
// create a `WebResponse` object to receive or understand the response from the corresponding server
WebResponse web_response = web_request.GetResponse();
header_cookie = web_response.Headers["Set-cookie"]; // `Set-cookie` as a web response header file
/*
GET
*/
// define a source page and the `GET` web URL
string source_page;
string web_URL_get =
"http://www.webpage_behind_the_login.com"; // mention the webpage behind the login form
// create a GET response
WebRequest web_request_get = WebRequest.Create(web_URL_get);
web_request_get.Headers.Add("Cookie", header_cookie);
// web_request_get.ContentLength = web_request.ContentLength;
WebResponse web_response_get = web_request_get.GetResponse();
using (StreamReader stream_reader_get = new StreamReader(web_response_get.GetResponseStream())) {
source_page = stream_reader_get.ReadToEnd();
}
以下は、C# プロジェクトにコピーして貼り付け、WebClient
を使用して Web サイトにログインできる C# コードです。 ただし、自分のユーザー名とパスワードを使用し、Web サイトの URL を入力することを忘れないでください。また、ログインに成功した後に C# プログラムがリダイレクトする Web ページについても忘れずに言及してください。
using System;
using System.Windows.Forms;
using System.Net;
// using System.Net.Http;
using System.Collections.Specialized;
namespace test_login {
// create a sub-class using `WebClient`
public class CookieAwareWebClient : WebClient {
// create a cookie container for web requests and web response
private CookieContainer website_cookie = new CookieContainer();
// overload using URI of the target web address
protected override WebRequest GetWebRequest(Uri trg_web_add) {
WebRequest tag_web_request = base.GetWebRequest(trg_web_add);
if (tag_web_request is HttpWebRequest) {
(tag_web_request as HttpWebRequest).CookieContainer =
website_cookie; // generate a proper request to the server
}
return tag_web_request;
}
}
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
// create a new user
var new_user = new CookieAwareWebClient();
// base address of the corresponding webpage (for login)
new_user.BaseAddress = @"https://www.example_website/some_page/login/url_address/";
// create a variable that carries the user information
var user_info = new NameValueCollection();
user_info.Add("username", "your_username"); // username or mail address
user_info.Add("password", "your_password"); // password
// upload the user information to the webpage
new_user.UploadValues("login_page.php", "POST", user_info);
// successfully login can request the pages, following
string source_html = new_user.DownloadString("website_homepage.php");
}
}
}
出力:
username: your_username
password: your_password
[redirect the user to the `index.php` after a successful login]
もう 1つの興味深いアイデアは、WebClient
から派生するクラスを作成してオーバーライドした後、GetWebRequest
メソッドに CookieContainer
オブジェクトを設定して、このアプローチを変更することです。 単一または同じ CookieContainer
インスタンスは、デフォルトで Cookie 管理を処理できます。
C#
で Web サイトにログインするスクリプトを作成する
プログラムによる Web サイトへのログインは、Web サイトがログイン手順を実装する方法と密接に関連しているため、各 Web サイトのログイン手順は一意であり、異なるプロトコルが必要です。 プロセスを理解し、それに応じて (サーバーへの、およびサーバーからの) 要求と応答を記述する必要があります。
Web サイトの手順を通過する非常に複雑で壊れやすいスクリプトを作成するのは簡単なことではありませんが、そうすることで、アプリケーションのセキュリティと有効性を高めることができます。 さらに、AllowAutoRedirect
をオフにして、POST
と GET
の両方のリクエストを同じユーザー エージェントに設定すると、次のようなことができます。
request.UserAgent = UserAgent;
// to eliminate any redirection to other website or webpage
request.AllowAutoRedirect = false;
一部の Web サイトは、ログインしようとすると暗号化された URL エンコードされた戻り値を送信します。サーバーが何かが欠けていることに気付いた場合、HTTP/1.1 400 Bad Request
のようなものをスローするか、サーバーからの 200 応答である可能性があります。 内部のどこかに埋め込まれたエラーメッセージ。 サーバーが違いを認識せずにログインできるように、適切な値を収集して HttpWebRequest
オブジェクトに渡す必要があります。
using System;
using System.Windows.Forms;
using System.Net;
// using System.Net.Http;
using System.IO;
// using System.Collections.Specialized;
namespace test_login {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
string user_name = UsernameBox.Username; // textbox that contains the user name
string user_password = PasswordBoxPassword.Password; // textbox that contains the password
// HTML IDs or important user information to perform a successful login against a specific
// user
string login_user_name = textBox1.Text; // username
string login_user_password = textBox2.Text; // password
// submit info for a successful login
string login_submit_info = textBox3.Text; // login submit
// define the website or webpage connection parameters
string post_method = "POST"; // `POST` method for web_request
string type_webcontent = @"c_sharp-application/encoded_url-www-form";
string string_login = login_user_name + "=" + user_name + "&" + login_user_password + "=" +
user_password + "&" + login_submit_info;
CookieContainer container_cookie = new CookieContainer();
HttpWebRequest web_request;
web_request = (HttpWebRequest)WebRequest.Create(
"http://www.example_url.com/login_page/"); // or insert the `url` string that contains
// the valid website URL
web_request.CookieContainer = container_cookie;
web_request.Method = post_method; // for web request
web_request.ContentType = type_webcontent;
web_request.KeepAlive = true;
using (Stream web_stream_request = web_request.GetRequestStream())
// generate a proper web request
using (StreamWriter writer = new StreamWriter(web_stream_request)) {
writer.Write(string_login, user_name, user_password);
}
using (var web_stream_response = web_request.GetResponse().GetResponseStream()) using (
var web_response_reader = new StreamReader(web_stream_response)) {
var user_check = web_response_reader.ReadToEnd();
Console.WriteLine(user_check); // the result
}
MessageBox.Show("Successful login to website!");
}
}
}
出力:
Successful login to website!
C#
で Selenium
を自動化して Web サイトにログインするスクリプトを作成する
手動のスクリプトを作成するのは面倒なので、selenium.WebDriver
を自動化するスクリプトを作成することは、プログラムで C# の Web サイトにログインするための有効なオプションです。 すべてのジャグリングを処理して、有効な Cookie を取得できるようにすることで、リクエストを正常にスローできます。
コードを最適化するには、selenium
を理解することが重要です。 たとえば、azure
にログインしてクレジットを取得すると、スクリプトの作成が非常に短くなります。 ただし、CookieContainer exp_cookie = new CookieContainer();
がないため、 つまり、CookieContainer
をサポートする Web サイトには適していません。
// Install `Selenium.WebDriver` NuGet Package
// Install `Selenium.WebDriver.ChromeDriver` NuGet Package
using System;
using System.Windows.Forms;
using System.Net;
// using System.Net.Http;
using System.IO;
// using System.Collections.Specialized;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
namespace login_website {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
// run selenium | starts from...
ChromeDriver chrome_driver = new ChromeDriver(
@"chromedriver_win32"); // install the selenium chrome web driver for `ChromeDriver`
chrome_driver.Url = @"https://fif.com/login";
chrome_driver.Navigate();
IWebElement web_element = chrome_driver.FindElementById(
"user_name"); // install selenium web driver to use `FindElementById()` method
web_element.SendKeys("...");
web_element = chrome_driver.FindElementById("user_password");
web_element.SendKeys("...");
web_element = chrome_driver.FindElementByXPath(
@"//*[@id=""main""]/div/div/div[2]/table/tbody/tr/td[1]/div/form/fieldset/table/tbody/tr[6]/td/button");
web_element.Click();
CookieContainer cookie_container = new CookieContainer();
// get the cookies from the website
foreach (OpenQA.Selenium.Cookie web_cookie in chrome_driver.Manage().Cookies.AllCookies) {
string user_name = web_cookie.Name;
string user_value = web_cookie.Value;
cookie_container.Add(
new System.Net.Cookie(user_name, user_value, web_cookie.Path, web_cookie.Domain));
}
// generate a proper web request
HttpWebRequest http_web_request = (HttpWebRequest)HttpWebRequest.Create(
"https://example.com/web_content/com_example/web_tools/page_capacity/login_values/"); // or something like "https://fif.com/components/com_fif/tools/capacity/values/"
http_web_request.CookieContainer = cookie_container;
http_web_request.Method = "POST";
http_web_request.ContentType = "application/x-www-form-urlencoded";
StreamWriter stream_writer = new StreamWriter(http_web_request.GetRequestStream());
stream_writer.Write("feeds=35");
stream_writer.Close();
WebResponse web_response = http_web_request.GetResponse();
string response_imp =
new System.IO.StreamReader(web_response.GetResponseStream()).ReadToEnd();
}
}
}
出力:
[redirect the user to the `index.php` after a successful login]
* or
[shows an error for wrong username or password for invalid user]
ブラウザーを自動化するために Selenium サーバーは必要ありません。 ネイティブ OS レベルのイベントを使用して JavaScript サンドボックスをバイパスし、ブラウザーを操作します。
さらに、簡潔でオブジェクトベースの Selenium WebDriver
API の .NET バインディングが含まれています。
Selenium にはさまざまなソフトウェア ツールがバンドルされており、それぞれがブラウザーの自動化をサポートするためのアプローチが異なります。 ブラウザー内の要素を見つけて操作するための非常に柔軟なツールを提供し、複数のブラウザー プラットフォームの自動化をサポートします。
C#
で HttpClient
を使用して Web サイトにログインする
リダイレクトのステータス コードは 3**
であるため、実際のログイン応答にアクセスするのに役立ちます。 HttpClient
でリダイレクトを無効にする必要があります。 HTTP 動詞
リクエスト メソッドを使用して URL をリクエストするための資格情報を送信します (または、ほとんどの場合、POST
メソッドを使用できます)。
サーバーがログインしたユーザーから受け取ることを期待する Cookie に基づいてログイン メソッドを実装することは常に簡単です。この情報は set-cookie
ヘッダーに含まれるデータに基づいています。
GET
には HTTP
本体が含まれていないため、HttpClient
で GET
および POST
メソッドを使用して Web サイトにログインできます。 POST
を使用すると、データは QueryString
から HTTP
本体に移動します。
ユーザー資格情報または渡すデータはパラメーターを介して渡され、残りはハードコーディングされます。 最も重要なことは、キーと値のペアのインスタンス (KeyValuePair<string, string>
) が、プログラムで Web サイトにログインするのに役立つフォーム データの指定されたシーケンスを表すことです。
場合によっては、ユーザーが指定したデータのみが必要になることがあります。Web サイトでログイン ページの非表示フィールドを含める必要がある場合は、Web サイトを要求し、AngleSharp
または同様の方法を使用して HTML を解析することが不可欠な手順です。
結論として、キーと値 (null 許容文字列) を含む結果のシーケンスが FormUrlEncodedContent
コンストラクターに渡されます (シーケンスのキーと値が null 許容文字列であることが想定されます)。
// try not to change the entry point of this C# code
// it's important to remember that the `website_login.Program.Main` in your C# project is the entry
// point of this C# program. changing the entry point can lead to many difficulties and logical or
// syntax errors
using System;
using System.Net;
using System.IO;
namespace website_login {
public class Program {
public static void Main(string[] args) {
var add_primary = new Uri("https://www.example_website.com/");
var container_cookie = new CookieContainer(); // for web request
// generate a proper web request | special HTTP implementation of the `WebRequest` class
HttpWebRequest post_request_web =
(HttpWebRequest)HttpWebRequest.Create("https://www.example_website.com/");
post_request_web.CookieContainer = container_cookie;
/*
* setting the agent (user_agent) and accepting the header values
* these are important to simulate a real web browser
*/
post_request_web.UserAgent =
"Chrome/5.3 (Windows Professional 11.2; WOW32) Chrome/45.0.2454.101"; // change it with
// respect to your
// platform, OS,
// and browser
post_request_web.Accept =
"text_type/html,c_sharp_application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; // set values
Console.WriteLine("[response from the server...]");
Console.WriteLine();
// generate a proper web response
using (WebResponse get_response_web = post_request_web.GetResponse()) {
// to read the response from the web server
using (StreamReader stream_reader =
new StreamReader(get_response_web.GetResponseStream())) {
Console.WriteLine(stream_reader.ReadToEnd()); // display
}
}
post_request_web = (HttpWebRequest)HttpWebRequest.Create("https://www.example_website.com/");
// setting `container_cookie` as a cookie container object
post_request_web.CookieContainer = container_cookie;
post_request_web.UserAgent =
"Chrome/5.3 (Windows Professional 11.2; WOW32) Chrome/45.0.2454.101"; // change it with
// respect to your
// platform, OS,
// and browser
post_request_web.Accept =
"text_type/html,c_sharp_application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; // set values
post_request_web.Method = "POST"; // POST method because of web request
post_request_web.ContentType =
"application/x-www-form-urlencoded"; // it is a standard content type
// the `user_infomration` variable contains the username and password of a user for login
string user_information =
string.Format("username={0}&password={1}", "your_username", "your_password");
// encode the user information to send it to the web server
byte[] _web_bytes = System.Text.Encoding.UTF8.GetBytes(user_information);
post_request_web.ContentLength = _web_bytes.Length;
using (Stream web_stream_user_info = post_request_web.GetRequestStream()) {
web_stream_user_info.Write(_web_bytes, 0, _web_bytes.Length);
web_stream_user_info.Close();
}
Console.WriteLine("[response form the server on user login...]");
Console.WriteLine();
using (WebResponse web_response_dll = post_request_web.GetResponse()) {
// to read the response from the web server
using (StreamReader stream_reader_dll =
new StreamReader(web_response_dll.GetResponseStream())) {
Console.WriteLine(stream_reader_dll.ReadToEnd()); // display
}
}
//....
}
}
}
出力:
[response from the server...]
... // some response from the website
*response from the `streamreader`*
[response from the server on user login...]
// response from the server or website after the first login attempt
FormUrlEncodedContent
コンストラクターのインスタンスは、PostAsync
呼び出しの POST
要求の主要なコンテンツです。この呼び出しを行った後の次のステップは、HTTP 応答から set-cookie
ヘッダーを解析することです。 .NET クラス ライブラリで適切な NuGet パッケージを見つけるのは常に難しい選択です。そのため、正規表現を使用して解析する方が優れた方法です。
応答 Cookie をチェックしてログインの失敗を検出するか、サーバーからの応答のステータス コードをチェックするか、サーバーから返された HTML コンテンツを解析します。 要求されたページをダウンロードする前に LoginAsync
を呼び出すことは、サーバーへの要求に使用するログイン Cookie を取得または返すための優れたオプションです。
組み込みの GetStringAsync
メソッドのオーバーロードに Cookie のパラメーターが含まれていない場合は、拡張メソッドを自分で作成します。次の C# コードでその作成を確認できます。 SendAsync
メソッドを使用して要求 (生成された HTTP 要求) を送信する前に、すべての Cookie を単一の cookie
ヘッダーに結合する必要があります。
ログイン応答ステータス コードでリダイレクトが必要な場合に、HttpClient
の自動リダイレクト機能を無効にする場合のオプションです。 これは、HttpClient
インスタンスを使用して行うことができます。依存性注入のために HttpClient
を登録するときにオプションを渡すことにより、IHttpClientFactory
でこれを行うことができるからです。
HttpClient
または .NET には組み込み機能がないため、一般に、プログラムで Web サイトにログインするには、すべての手順を手動で実行する必要があり、毎回プロセスが異なる可能性があります。 認証またはログイン データは Cookie に設定されるため、CookieContainer
を設定して、HttpClient
を使用して標準の FormsAuthentication
Web サイトでログインを実行します。
Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.
GitHub