背景
友達に自動予約ツールを作れほしいと頼まれましたので、ブラウザを自動操作し、2秒以内に予約確定が必要とのことでした。手動で予約を取るときに、コース予約が大人気のため、なかなか予約を取れずにこの依頼に至りました。
上記の自動予約ツール以外にもブラウザ自動操作ができれば、いろなことができるはずです。リアル売買の自動処理とか株の売買も高額の資金の管理は決定権は人に任せたほうが良いですが、多少アルゴリズムにジャージのサポートはほしいですよね。あとは、物販の販売にも定期的に自動出品も可能になります。
C#コンソールアプリのプロジェクトを作成する
VisualStudioを立ち上げ、C#のコンソールアプリを作成します。
Selenium
を使えるようにNuGet
より2つのパッケージをダウンロードします。
- Selenium.WebDriver
- Selenium.WebDriver.ChromeDriver
C# Selenium Chromeを自動で開く
using System;
using System.IO;
using System.Reflection;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace gymReserve
{
class Program
{
static void Main(string[] args)
{
// Webドライバーのインスタンス化
IWebDriver driver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
// URLに移動します。
driver.Navigate().GoToUrl(@"https://www.yahoo.co.jp/");
// なにかコンソールに文字を入力したらクロームを閉じる
Console.ReadKey();
driver.Quit();
}
}
}
C#でINIファイル読み込み
iniファイルを準備する
[SETTING]
;ID
ID=XXXX
;パスワード
PASSWORD=XXXX
;予約パスワード
RESERVATION_PASSWORD=XXXX
;予約タイムラグ(ms)
WAIT_TIME=100
;リトライ回数
RETRY_COUNT=10
;リトライ間隔(秒)
RETRY_INTERVAL=2
C#でiniファイル読み込むクラスを用意する
class CSharpIni
{
// DLL関数の定義です。
[DllImport("KERNEL32.DLL")]
public static extern uint GetPrivateProfileString(
string lpAppName,
string lpKeyName,
string lpDefault,
StringBuilder lpReturnedString,
uint nSize,
string lpFileName);
[DllImport("KERNEL32.DLL")]
public static extern uint GetPrivateProfileInt(
string lpAppName,
string lpKeyName,
int nDefault,
string lpFileName);
// DLL関数をラップしたメソッドです。
public string GetValueString(string section, string key, string fileName)
{
var sb = new StringBuilder(1024);
GetPrivateProfileString(section, key, "", sb, Convert.ToUInt32(sb.Capacity), fileName);
return sb.ToString();
}
public int GetValueInt(string section, string key, string fileName)
{
var sb = new StringBuilder(1024);
return (int)GetPrivateProfileInt(section, key, 0, fileName);
}
}
C#でiniファイルを読み込み
//iniファイル読み込み
var readIniFile = new CSharpIni();
var ID = readIniFile.GetValueString("SETTING", "ID", ".\\設定情報.ini");
var PASSWORD = readIniFile.GetValueString("SETTING", "PASSWORD", ".\\設定情報.ini");
var RESERVATION_PASSWORD = readIniFile.GetValueString("SETTING", "RESERVATION_PASSWORD", ".\\設定情報.ini");
var WAIT_TIME = readIniFile.GetValueString("SETTING", "WAIT_TIME", ".\\設定情報.ini");
int RETRY_COUNT = readIniFile.GetValueInt("SETTING", "RETRY_COUNT", ".\\設定情報.ini");
int RETRY_INTERVAL = readIniFile.GetValueInt("SETTING", "RETRY_INTERVAL", ".\\設定情報.ini");
C#でCSVファイル読み込み
CSVファイルを準備する
有料/無料区分,店舗,曜日,開始時間帯,プログラム名
無料,XXX,月,13時台,XXX
有料,XXX,火,21時台,XXX
有料,XXX,水,22時台,XXX
無料,XXX,木,15時台,XXX
無料,XXX,金,18時台,XXX
無料,XXX,土,19時台,XXX
CSVライブラリを参照する
using Csv; // ライブラリCsv を使うのに必要です
C#でCSVファイルを文字列として取得
//CSVファイル読み込み
// ファイルの全内容を文字列に読込みます
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
string csv = File.ReadAllText(@".\XXXX.csv", Encoding.GetEncoding("Shift_JIS"));
C#でCSVファイルの行毎にLoop
//CSVファイルの行ごとにループ
foreach (ICsvLine line in CsvReader.ReadFromText(csv))
C#でCSVファイルの行のカラム項目を取得
string clock = line[@"開始時間帯"];
HTML要素の操作
IWebElement element = driver.FindElement(By.Id("ここにIDを入力"));
F12ボタンを押し、Chromeの開発者ツール(ディベロッパーツール)からウェブ要素を確認することができます。
WebDriverには標準のロケータが8種類あります。
https://www.selenium.dev/ja/documentation/webdriver/elements/locators/
ロケータ | 詳細 |
---|---|
class name | class名に値を含む要素を探す (複合クラス名は使えない) |
css selector | CSSセレクタが一致する要素を探す |
id | id属性が一致する要素を探す |
name | name属性が一致する要素を探す |
link text | a要素のテキストが一致する要素を探す |
partial link text | a要素のテキストが部分一致する要素を探す |
tag name | タグ名が一致する要素を探す |
xpath | XPathと一致する要素を探す |
HTML要素のプルダウン選択
//検索条件入力画面
IWebElement selectElement = driver.FindElement(By.Name("XXXX"));
var selectObject = new SelectElement(selectElement);
// Select an <option> based upon its text
selectObject.SelectByText(line[@"有料/無料区分"]);
HTML要素複数checkBox選択
IList<IWebElement> elements = driver.FindElements(By.Name("dow[]"));
foreach (IWebElement e in elements)
if e.GetAttribute("value")= line[@"曜日"]
e.Click();
HTML要素button押す操作
//ボタンを押す操作
driver.FindElement(By.ClassName("btn")).Click();
//ボタンを押す操作
driver.FindElement(By.ClassName("btn")).Submit();
HTML要素button複数がある場合の配列処理
driver.FindElements(By.Name("id"))[1].SendKeys(ID);
HTML要素の文字列を入力
driver.FindElement(By.Name("pw")).SendKeys(RESERVATION_PASSWORD);
HTML要素の入力テキストをクリア
driver.FindElement(By.Name("XXXX")).Clear();
HTML要素文字列取得と判定
string resulText = driver.FindElement(By.ClassName("mgb15")).Text;
if (resulText.Contains("ありません"))
...
}
HTML要素取得の待ち処理
Thread.Sleep(RETRY_INTERVAL * 1000);
Chrome F5 Refresh更新処理
driver.Navigate().Refresh();
Chrome終了させる処理
driver.Quit();
Environment.Exit(0);
参考サイト
- https://www.selenium.dev/ja/documentation/webdriver/
- https://www.hanachiru-blog.com/entry/2020/03/12/120000
- https://c-taquna.hatenablog.com/entry/2019/05/27/004135
- https://www.toolsqa.com/selenium-c-sharp/
- https://qiita.com/ymk1102_1t/items/42aa7c588ce97e3312b6
- https://codechacha.com/ja/selenium-explicit-implicit-wait/
- https://www.fenet.jp/dotnet/column/language/python/7851/#PythonSelenium%E3%81%A7%E3%81%AEwait%E3%81%AE%E6%96%B9%E6%B3%95%E3%81%A8%E3%81%AF%EF%BC%9F ページ遷移の待機方法 Python
- https://www.webdevqa.jp.net/ja/c%23/selenium-c%EF%BC%83webdriver%EF%BC%9A%E8%A6%81%E7%B4%A0%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%82%8B%E3%81%BE%E3%81%A7%E5%BE%85%E3%81%A4/940710157/ ページ遷移の待機方法 C#
- https://www.selenium.dev/ja/documentation/webdriver/waits/ 待機方法
- https://tech-and-investment.com/csv2/ csvファイル読み込みと使用方法
コメント