/// <summary> /// 最新予約取得を実行する /// </summary> /// <returns></returns> public CheckReservationResult Execute() { var ret = default(CheckReservationResult); // ドライバ初期化 using (var driver = WebDriverFactory.CreateInstance(AppSettings.BrowserName.Chrome)) { // アクセス driver.Url = String.Format("{0}mypage/reservation/?lcl_id=ja", SiteConfig.BASE_URL); // ログイン試行 if (!TryLogin(driver)) { // ログイン失敗 ret = CheckReservationResult.LoginFailed; _reservationItem = null; } else { try { // ホテル名 string name = driver.FindElement(By.XPath(SiteConfig.XPATH_RESERVATION_NAME)).Text; // チェックイン日時 string date = driver.FindElement(By.XPath(SiteConfig.XPATH_RESERVATION_DATE)).Text.Split(new string[] { "\r\n" }, StringSplitOptions.None)[0]; // 予約あり ret = CheckReservationResult.Found; _reservationItem = new ReservationItem() { Name = name, Date = date }; } catch (NoSuchElementException) { // 予約なし ret = CheckReservationResult.NotFound; _reservationItem = null; } } } return(ret); }
private static void Main(string[] args) { ServicePointManager.Expect100Continue = false; using (var webDriver = WebDriverFactory.CreateInstance(AppSettings.BrowserName.InternetExplorer)) { try { // Scenario1(webDriver); // Scenario2(webDriver); Scenario3(webDriver); } catch (Exception e) { Console.WriteLine(e.Message); } // ブラウザを閉じる webDriver.Quit(); } }
/// <summary> /// 予約を実行する(キャンセルチェックが多すぎて頭悪い) /// </summary> /// <returns></returns> public bool Execute() { bool ret = false; log.Debug(String.Format("処理を開始しました")); log.Debug(String.Format("> ホテルID :{0}", ProcFormat.HotelID.HotelID)); log.Debug(String.Format("> チェックイン:{0}", ProcFormat.CheckinDate.ToString("yyyy/MM/dd"))); // ログのファイル数を管理 //FileManager.RemoveFileObsolete(String.Format(@"{0}\AutomaticReservation_UI\log", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)), "log", _logConfig.MaxLogCount); log.Debug("ドライバ初期化中"); Message = "ドライバ初期化中"; using (var driver = WebDriverFactory.CreateInstance(AppSettings.BrowserName.Chrome)) { // 仮想画面サイズ設定 driver.Manage().Window.Size = new System.Drawing.Size(1920, 1080); #region 初期処理 // アクセス Message = "アクセス中"; log.Debug(String.Format("アクセス中:{0}", SiteConfig.BASE_URL)); driver.Url = SiteConfig.BASE_URL; if (CheckCancel()) { log.Debug("キャンセルされました"); Message = "キャンセルされました"; return(ret); } // 詳細ページへ log.Debug(String.Format("詳細ページへ移動中:{0}", String.Format("{0}search/detail//{1}", SiteConfig.BASE_URL, ProcFormat.HotelID.HotelID))); Message = "詳細ページへ移動中"; driver.Url = String.Format("{0}search/detail//{1}", SiteConfig.BASE_URL, ProcFormat.HotelID.HotelID); if (CheckCancel()) { log.Debug("キャンセルされました"); Message = "キャンセルされました"; return(ret); } #endregion ExecutionState.DisableSuspend(); #region 無限ループ while (true) { try { Count += 1; log.Debug("--------------------------------------------------"); log.Debug(String.Format("継続回数:{0}", Count)); // 予約ページへ log.Debug(String.Format("予約ページへ移動中:{0}", String.Format("{0}search/reserve/room?chckn_date={1}&room_type={2}", SiteConfig.BASE_URL, ProcFormat.CheckinDate.ToString("yyyy/MM/dd"), ProcFormat.Type.RoomTypeID.ToString()))); Message = "予約ページへ移動中"; driver.Url = String.Format("{0}search/reserve/room?chckn_date={1}&room_type={2}", SiteConfig.BASE_URL, ProcFormat.CheckinDate.ToString("yyyy/MM/dd"), ProcFormat.Type.RoomTypeID.ToString()); if (CheckCancel()) { log.Debug("キャンセルされました"); Message = "キャンセルされました"; break; } #region 禁煙・喫煙による分岐 // 20180222 禁煙・喫煙の該当する部屋タイプを全て検索するよう変更 if (!ProcFormat.EnableNoSmoking && !ProcFormat.EnableSmoking) { // 禁煙・喫煙両方0だった場合、エラー // UIで阻止済 } else if (ProcFormat.EnableNoSmoking && ProcFormat.EnableSmoking) { // 禁煙・喫煙両方1だった場合 if (!ProcFormat.SmokingFirst) { // 禁煙を優先 ret = SearchRoom(driver, "禁煙"); if (ret) { log.Debug("禁煙 空室あり"); Message = "禁煙 空室あり"; } else { // print 満室 ret = SearchRoom(driver, "喫煙"); if (ret) { log.Debug("喫煙 空室あり"); Message = "喫煙 空室あり"; } else { log.Debug("満室"); Message = "満室"; } } } else { // 喫煙を優先 ret = SearchRoom(driver, "喫煙"); if (ret) { log.Debug("喫煙 空室あり"); Message = "喫煙 空室あり"; } else { // print 満室 ret = SearchRoom(driver, "禁煙"); if (ret) { log.Debug("禁煙 空室あり"); Message = "禁煙 空室あり"; } else { log.Debug("満室"); Message = "満室"; } } } } else if (ProcFormat.EnableNoSmoking) { // 禁煙 ret = SearchRoom(driver, "禁煙"); if (ret) { log.Debug("禁煙 空室あり"); Message = "禁煙 空室あり"; } else { log.Debug("禁煙 満室"); Message = "禁煙 満室"; } } else { // 喫煙 ret = SearchRoom(driver, "喫煙"); if (ret) { log.Debug("喫煙 空室あり"); Message = "喫煙 空室あり"; } else { log.Debug("喫煙 満室"); Message = "喫煙 満室"; } } if (CheckCancel()) { log.Debug("キャンセルされました"); Message = "キャンセルされました"; break; } #endregion // ログイン試行 if (!TryLogin(driver)) { log.Fatal("ログインに失敗"); log.Info("このエラーは自動リトライできません"); Message = "ログインに失敗"; return(ret); } #region 空室発見~予約確定 if (ret) { log.Debug("予約中"); Message = "予約中"; // 電話番号入力 log.Debug(String.Format("処理中:{0}", SiteConfig.XPATH_TEL)); driver.FindElement(By.XPath(SiteConfig.XPATH_TEL)).SendKeys(_loginInfo.LoginTel); // チェックイン予定時刻 log.Debug(String.Format("処理中:{0}", SiteConfig.XPATH_CHKINTIME)); var chktime_element = driver.FindElement(By.XPath(SiteConfig.XPATH_CHKINTIME)); var chktime_select_element = new SelectElement(chktime_element); chktime_select_element.SelectByValue(ProcFormat.CheckinValue.CheckinValue); // 確認ボタン押下 log.Debug(String.Format("処理中:{0}", SiteConfig.XPATH_CONFIRM)); driver.FindElement(By.XPath(SiteConfig.XPATH_CONFIRM)).Click(); // 同一日で予約があった場合 try { // Waitオブジェクトを定義 var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 3)); // iframeに操作をスイッチ wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector(SiteConfig.IFRAME_OVERWRITE))); log.Debug(String.Format("処理中:{0}", SiteConfig.XPATH_OVERWRITE)); if (SiteConfig.STR_OVERWRITE.Equals(driver.FindElement(By.XPath(SiteConfig.XPATH_OVERWRITE)).Text)) { if (ProcFormat.EnableOverwrite) { driver.FindElement(By.XPath(SiteConfig.XPATH_BTN_OVERWRITE)).Click(); } } else { // raise } } catch (NoSuchElementException) { // 何もしない } catch (WebDriverTimeoutException) { // 何もしない } // 予約&正常終了確認 try { // 20180407 規約に同意チェック欄対応 // チェックボックスにチェック log.Debug(string.Format("処理中:{0}", SiteConfig.XPATH_CHKAGREE)); driver.FindElement(By.XPath(SiteConfig.XPATH_CHKAGREE)).Click(); // 確定ボタン押下 log.Debug(string.Format("処理中:{0}", SiteConfig.XPATH_OK)); driver.FindElement(By.XPath(SiteConfig.XPATH_OK)).Click(); log.Debug(string.Format("処理中:{0}", SiteConfig.XPATH_CHK_VALIDATE)); string str_chk = driver.FindElement(By.XPath(SiteConfig.XPATH_CHK_VALIDATE)).Text; if (!(str_chk.Equals(SiteConfig.STR_VALIDATE))) { // 要素はあるが文字が違う log.Debug("予約できませんでした(文字列が異なります)"); Message = "予約できませんでした"; ret = false; if (ProcFormat.EnableAutoRetry) { log.Info("処理を続行します"); } else { break; } } } catch (NoSuchElementException) { // 要素がない log.Debug("予約できませんでした(要素が存在しません)"); Message = "予約できませんでした"; ret = false; if (ProcFormat.EnableAutoRetry) { log.Info("処理を続行します"); } else { break; } } if (ret) { log.Debug("予約完了"); Message = "予約完了"; break; } } #endregion } catch (Exception ex) { log.Error(ex.ToString()); if (ProcFormat.EnableAutoRetry) { log.Info("処理を続行します"); } else { break; } } // 適当な秒数待つ int threadSleep = new Random().Next(SiteConfig.MIN_THREAD_SLEEP_MILLISEC, SiteConfig.MAX_THREAD_SLEEP_MILLISEC); log.Debug(String.Format("スレッド処理を {0} 秒待機します", threadSleep / 1000)); Message = "スレッド待機中..."; // キャンセル可能なスレッド休止にした if (CancelToken.WaitHandle.WaitOne(threadSleep)) { log.Debug("キャンセルされました"); Message = "キャンセルされました"; break; } } #endregion } log.Debug(String.Format("処理を終了しました(戻り値:{0})", ret)); return(ret); }
/// <summary> /// 実行する /// </summary> public void Execute() { HotelList = new ObservableCollection <Hotel>(); // ドライバ初期化 using (var driver = WebDriverFactory.CreateInstance(AppSettings.BrowserName.Chrome)) { // 都道府県コード int pref_code = 0; // その地域の都道府県リスト var pref_names = new List <string>(); // アクセス driver.Url = String.Format("{0}hotel_list/?lcl_id=ja", SiteConfig.BASE_URL); // 地域で繰り返す(7地域) for (int iter_region = 1; iter_region <= 7; iter_region++) { // ----- ----- ----- ----- ----- // 地域ごとに変数を初期化 // ----- ----- ----- ----- ----- pref_names = new List <string>(); int iter_pref = 1; int iter_hotel = 1; // その地域の都道府県一覧取得 while (true) { try { // 都道府県名 string pref_name = driver.FindElement(By.XPath(SiteConfig.XPATH_PREFNAME.Replace("ITER_REGION", iter_region.ToString()).Replace("ITER_PREF", iter_pref.ToString()))).Text; // リストに追加 pref_names.Add(pref_name); // 都道府県イテレータを回す iter_pref++; } catch (NoSuchElementException) { // 要素がもうない break; } catch { // raise exception } } // その地域のホテル取得 while (true) { try { // ホテルID string hotel_id = driver.FindElement(By.XPath(SiteConfig.XPATH_HOTELID.Replace("ITER_REGION", iter_region.ToString()).Replace("ITER_HOTEL", iter_hotel.ToString()))).Text; // 0埋めして5桁にする hotel_id = String.Concat("00", hotel_id); // ホテル名 string hotel_name = driver.FindElement(By.XPath(SiteConfig.XPATH_HOTELNAME.Replace("ITER_REGION", iter_region.ToString()).Replace("ITER_HOTEL", iter_hotel.ToString()))).Text; // 「東横INN」があると長くなるので消す hotel_name = hotel_name.Replace("東横INN", ""); // 住所 string hotel_address = driver.FindElement(By.XPath(SiteConfig.XPATH_ADDRESS.Replace("ITER_REGION", iter_region.ToString()).Replace("ITER_HOTEL", iter_hotel.ToString()))).Text; bool is_oversea = false; // 住所の先頭文字列を読んで都道府県を特定する foreach (string one_pref in pref_names) { if (hotel_address.Contains(one_pref)) { try { // 都道府県コード設定 pref_code = PrefCodeList.Where(item => item.PrefName.Equals(one_pref)).First().ID; break; } catch { // 海外フラグをオンにしてbreak is_oversea = true; break; } } } // 海外の時はcontinue if (is_oversea) { iter_hotel++; continue; } // 要素を追加 HotelList.Add(new Hotel() { HotelID = hotel_id, HotelName = hotel_name, PrefCode = pref_code }); } catch (NoSuchElementException) { // 要素がもうない break; } catch { // raise exception } iter_hotel++; } } // csvファイルに出力 XmlConverter.SerializeFromCol(HotelList, String.Format(@"{0}\HotelList.xml", SiteConfig.BASE_DIR)); // 処理成功 Result = true; } }