refactor: Chrome 옵션 중복 제거 및 코드 구조 개선

This commit is contained in:
2025-08-12 00:18:04 +09:00
parent 2f1c2483f0
commit 7ca6712e29
24 changed files with 1065 additions and 2301 deletions

View File

@@ -9,6 +9,7 @@ using WebDriverManager.DriverConfigs.Impl;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using UniMarc.;
namespace BokBonCheck
{
@@ -116,7 +117,7 @@ namespace BokBonCheck
}
return true;
}
catch(Exception ex)
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
@@ -130,7 +131,7 @@ namespace BokBonCheck
SiteName = "남구통합도서관(효천어울림도서관)";
}
protected override bool SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
@@ -176,11 +177,11 @@ namespace BokBonCheck
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if ( searchBox.Selected == true)
if (searchBox.Selected == true)
{
SafeClick(searchBox);
}
selector = "#libSQ";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
@@ -203,7 +204,7 @@ namespace BokBonCheck
public string SiteName { get; protected set; } = "남구통합도서관(전체)";
public string SiteUrl => "https://lib.namgu.gwangju.kr/main/bookSearch";
public int No { get; set; }
public int No { get; set; }
private ChromeDriver _driver;
private ChromeDriverService _service;
@@ -219,28 +220,56 @@ namespace BokBonCheck
this.No = no;
}
public void StartDriver()
//public async Task StartDriverAsync(bool showdriver=false)
//{
// if (_driver == null)
// {
// try
// {
// // ChromeDriverManager를 사용하여 안정적으로 드라이버 설정
// var driverPath = await ChromeDriverManager.SetupChromeDriverAsync();
// // ChromeDriver 서비스 생성
// _service = ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(driverPath), Path.GetFileName(driverPath));
// _service.HideCommandPromptWindow = true;
// // 안정적인 Chrome 옵션 가져오기 (브라우저 창 숨김)
// var options = ChromeDriverManager.CreateBaseChromeOptions(!showdriver);
// // 추가 보안 및 안정성 옵션
// options.AddArgument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36");
// options.AddArgument("--disable-blink-features=AutomationControlled");
// options.AddExcludedArgument("enable-automation");
// options.AddAdditionalOption("useAutomationExtension", false);
// // ChromeDriver 생성
// _driver = new ChromeDriver(_service, options);
// // 웹드라이버 감지 방지
// ((IJavaScriptExecutor)_driver).ExecuteScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})");
// Console.WriteLine("NamguLibrarySearcher ChromeDriver 초기화 완료");
// }
// catch (Exception ex)
// {
// Console.WriteLine($"ChromeDriver 초기화 실패: {ex.Message}");
// throw new InvalidOperationException($"ChromeDriver 초기화에 실패했습니다: {ex.Message}", ex);
// }
// }
//}
// 기존 StartDriver 메서드를 유지하여 호환성 보장
public void StartDriver(bool showBrowser)
{
if (_driver == null)
try
{
var driverPath = ChromeDriverManager.GetDriverPath();
if (string.IsNullOrEmpty(driverPath) || !File.Exists(driverPath))
{
driverPath = ChromeDriverManager.SetupChromeDriverAsync().GetAwaiter().GetResult();
}
_service = ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(driverPath), Path.GetFileName(driverPath));
_service.HideCommandPromptWindow = true;
var options = new ChromeOptions();
options.AddArgument("--no-sandbox");
options.AddArgument("--disable-dev-shm-usage");
options.AddArgument("--disable-gpu");
options.AddArgument("--window-size=640,700");
options.AddArgument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36");
options.AddArgument("--disable-blink-features=AutomationControlled");
options.AddExcludedArgument("enable-automation");
options.AddAdditionalOption("useAutomationExtension", false);
_driver = new ChromeDriver(_service, options);
((IJavaScriptExecutor)_driver).ExecuteScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})");
// 동기적으로 실행 (권장하지 않음)
StartDriverAsync(showBrowser).GetAwaiter().GetResult();
}
catch (Exception ex)
{
Console.WriteLine($"StartDriver 실패: {ex.Message}");
throw;
}
}
@@ -259,6 +288,45 @@ namespace BokBonCheck
}
}
public async Task StartDriverAsync(bool showdriver = false)
{
if (_driver == null)
{
try
{
// ChromeDriverManager를 사용하여 안정적으로 드라이버 설정
var driverPath = await ChromeDriverManager.SetupChromeDriverAsync();
// ChromeDriver 서비스 생성
_service = ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(driverPath), Path.GetFileName(driverPath));
_service.HideCommandPromptWindow = true;
// 안정적인 Chrome 옵션 가져오기 (브라우저 창 숨김)
var options = ChromeDriverManager.CreateBaseChromeOptions(!showdriver);
// 추가 보안 및 안정성 옵션
options.AddArgument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36");
options.AddArgument("--disable-blink-features=AutomationControlled");
options.AddExcludedArgument("enable-automation");
options.AddAdditionalOption("useAutomationExtension", false);
// ChromeDriver 생성
_driver = new ChromeDriver(_service, options);
// 웹드라이버 감지 방지
((IJavaScriptExecutor)_driver).ExecuteScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})");
Console.WriteLine("NamguLibrarySearcher ChromeDriver 초기화 완료");
}
catch (Exception ex)
{
Console.WriteLine($"ChromeDriver 초기화 실패: {ex.Message}");
throw new InvalidOperationException($"ChromeDriver 초기화에 실패했습니다: {ex.Message}", ex);
}
}
}
virtual protected bool SelectLibrary(WebDriverWait wait)
{
@@ -330,8 +398,11 @@ namespace BokBonCheck
try
{
// 드라이버가 없으면 자동으로 시작
if (_driver == null)
throw new InvalidOperationException("드라이버가 시작되지 않았습니다. StartDriver()를 먼저 호출하세요.");
{
await StartDriverAsync();
}
_driver.Navigate().GoToUrl(SiteUrl);
@@ -347,7 +418,7 @@ namespace BokBonCheck
//}
//대상도서관 선택
if(SelectLibrary(wait)==false)
if (SelectLibrary(wait) == false)
{
result.ErrorMessage = "도서관선택실패";
result.BookCount = -1;
@@ -496,7 +567,7 @@ namespace BokBonCheck
var match = System.Text.RegularExpressions.Regex.Match(text, @"전체\s*(\d+)");
if (match.Success)
{
if(int.TryParse(match.Groups[1].Value,out int vqty)==false)
if (int.TryParse(match.Groups[1].Value, out int vqty) == false)
{
errmessage = $"수량값오류({match.Groups[1].Value})";
return -1;
@@ -521,7 +592,7 @@ namespace BokBonCheck
}
}
// 페이지 변경을 감지하는 메서드
public async Task WaitForPageChange(WebDriverWait wait)
@@ -540,9 +611,22 @@ namespace BokBonCheck
// 방법 5: 특정 텍스트가 페이지에 나타날 때까지 대기
wait.Until(d =>
{
var pageText = d.FindElement(By.ClassName("search-result")).Text;
if (pageText.Contains("검색결과가 없습니다")) return true;
return pageText.Contains("에 대하여") && pageText.Contains("검색되었습니다");
try
{
var byclassname = By.ClassName("search-result");
var elm = d.FindElement(byclassname);
if (elm == null)
{
return false;
}
var pageText = elm.Text;
if (pageText.Contains("검색결과가 없습니다")) return true;
return pageText.Contains("에 대하여") && pageText.Contains("검색되었습니다");
}
catch
{
return false;
}
});
}