2025-07-06 19:30~ 21:35, 10:30 ~
Chrome Web Driver 추가(신규 복본검사 로직용) 도서관 검색버튼 추가 도서관 선택없이 검색시작을 누르면 오류 표시 도서관 DB 정보에 신규로직용 식별 키(SearcherNo:int) 추가 - 광주광역시 남구 (문화, 청소년, 스마트, 푸른길)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
@@ -18,12 +18,8 @@
|
||||
</basicHttpBinding>
|
||||
</bindings>
|
||||
<client>
|
||||
<endpoint address="http://testws.baroservice.com/FAX.asmx" binding="basicHttpBinding"
|
||||
bindingConfiguration="BaroService_FAXSoap" contract="BaroService_API.BaroService_FAXSoap"
|
||||
name="BaroService_FAXSoap" />
|
||||
<endpoint address="https://testws.baroservice.com/TI.asmx" binding="basicHttpBinding"
|
||||
bindingConfiguration="BaroService_TISoap" contract="BaroService_TI.BaroService_TISoap"
|
||||
name="BaroService_TISoap" />
|
||||
<endpoint address="http://testws.baroservice.com/FAX.asmx" binding="basicHttpBinding" bindingConfiguration="BaroService_FAXSoap" contract="BaroService_API.BaroService_FAXSoap" name="BaroService_FAXSoap" />
|
||||
<endpoint address="https://testws.baroservice.com/TI.asmx" binding="basicHttpBinding" bindingConfiguration="BaroService_TISoap" contract="BaroService_TI.BaroService_TISoap" name="BaroService_TISoap" />
|
||||
</client>
|
||||
</system.serviceModel>
|
||||
<runtime>
|
||||
@@ -32,6 +28,22 @@
|
||||
<assemblyIdentity name="Renci.SshNet" publicKeyToken="1cee9f8bde3db106" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2020.0.1.0" newVersion="2020.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<userSettings>
|
||||
|
||||
25
unimarc/unimarc/Main.Designer.cs
generated
25
unimarc/unimarc/Main.Designer.cs
generated
@@ -132,6 +132,7 @@
|
||||
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.IPText = new System.Windows.Forms.ToolStripLabel();
|
||||
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
|
||||
this.lblStatus = new System.Windows.Forms.ToolStripLabel();
|
||||
this.menuStrip1.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.toolStrip1.SuspendLayout();
|
||||
@@ -761,48 +762,48 @@
|
||||
this.이용자관리ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.신규사업자등록ToolStripMenuItem});
|
||||
this.이용자관리ToolStripMenuItem.Name = "이용자관리ToolStripMenuItem";
|
||||
this.이용자관리ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.이용자관리ToolStripMenuItem.Size = new System.Drawing.Size(178, 22);
|
||||
this.이용자관리ToolStripMenuItem.Text = "이용자 관리";
|
||||
//
|
||||
// 신규사업자등록ToolStripMenuItem
|
||||
//
|
||||
this.신규사업자등록ToolStripMenuItem.Name = "신규사업자등록ToolStripMenuItem";
|
||||
this.신규사업자등록ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.신규사업자등록ToolStripMenuItem.Size = new System.Drawing.Size(138, 22);
|
||||
this.신규사업자등록ToolStripMenuItem.Text = "사업자 관리";
|
||||
this.신규사업자등록ToolStripMenuItem.Click += new System.EventHandler(this.신규사업자등록ToolStripMenuItem_Click);
|
||||
//
|
||||
// 공지발송ToolStripMenuItem1
|
||||
//
|
||||
this.공지발송ToolStripMenuItem1.Name = "공지발송ToolStripMenuItem1";
|
||||
this.공지발송ToolStripMenuItem1.Size = new System.Drawing.Size(180, 22);
|
||||
this.공지발송ToolStripMenuItem1.Size = new System.Drawing.Size(178, 22);
|
||||
this.공지발송ToolStripMenuItem1.Text = "공지 발송";
|
||||
this.공지발송ToolStripMenuItem1.Click += new System.EventHandler(this.공지발송ToolStripMenuItem1_Click);
|
||||
//
|
||||
// 매출내역ToolStripMenuItem
|
||||
//
|
||||
this.매출내역ToolStripMenuItem.Name = "매출내역ToolStripMenuItem";
|
||||
this.매출내역ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.매출내역ToolStripMenuItem.Size = new System.Drawing.Size(178, 22);
|
||||
this.매출내역ToolStripMenuItem.Text = "매출내역";
|
||||
this.매출내역ToolStripMenuItem.Click += new System.EventHandler(this.매출내역ToolStripMenuItem_Click);
|
||||
//
|
||||
// 이용자거래처조회ToolStripMenuItem
|
||||
//
|
||||
this.이용자거래처조회ToolStripMenuItem.Name = "이용자거래처조회ToolStripMenuItem";
|
||||
this.이용자거래처조회ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.이용자거래처조회ToolStripMenuItem.Size = new System.Drawing.Size(178, 22);
|
||||
this.이용자거래처조회ToolStripMenuItem.Text = "이용자 거래처 조회";
|
||||
this.이용자거래처조회ToolStripMenuItem.Click += new System.EventHandler(this.이용자거래처조회ToolStripMenuItem_Click);
|
||||
//
|
||||
// 마크설정ToolStripMenuItem
|
||||
//
|
||||
this.마크설정ToolStripMenuItem.Name = "마크설정ToolStripMenuItem";
|
||||
this.마크설정ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.마크설정ToolStripMenuItem.Size = new System.Drawing.Size(178, 22);
|
||||
this.마크설정ToolStripMenuItem.Text = "마크설정";
|
||||
this.마크설정ToolStripMenuItem.Click += new System.EventHandler(this.마크설정ToolStripMenuItem_Click);
|
||||
//
|
||||
// 일괄처리관리ToolStripMenuItem
|
||||
//
|
||||
this.일괄처리관리ToolStripMenuItem.Name = "일괄처리관리ToolStripMenuItem";
|
||||
this.일괄처리관리ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.일괄처리관리ToolStripMenuItem.Size = new System.Drawing.Size(178, 22);
|
||||
this.일괄처리관리ToolStripMenuItem.Text = "일괄처리 관리";
|
||||
this.일괄처리관리ToolStripMenuItem.Click += new System.EventHandler(this.일괄처리관리ToolStripMenuItem_Click);
|
||||
//
|
||||
@@ -1008,7 +1009,8 @@
|
||||
this.botUserLabel,
|
||||
this.toolStripSeparator2,
|
||||
this.toolStripSeparator3,
|
||||
this.IPText});
|
||||
this.IPText,
|
||||
this.lblStatus});
|
||||
this.toolStrip1.Location = new System.Drawing.Point(0, 681);
|
||||
this.toolStrip1.Name = "toolStrip1";
|
||||
this.toolStrip1.Size = new System.Drawing.Size(1259, 25);
|
||||
@@ -1057,6 +1059,12 @@
|
||||
this.IPText.Size = new System.Drawing.Size(154, 22);
|
||||
this.IPText.Text = "접속 아이피 : 0.000.00.000";
|
||||
//
|
||||
// lblStatus
|
||||
//
|
||||
this.lblStatus.Name = "lblStatus";
|
||||
this.lblStatus.Size = new System.Drawing.Size(27, 22);
|
||||
this.lblStatus.Text = "WD";
|
||||
//
|
||||
// Main
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
|
||||
@@ -1188,5 +1196,6 @@
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
|
||||
public System.Windows.Forms.ToolStripLabel IPText;
|
||||
private System.Windows.Forms.ToolStripLabel lblStatus;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ using UniMarc.마크;
|
||||
using UniMarc.Properties;
|
||||
using UniMarc;
|
||||
|
||||
|
||||
namespace WindowsFormsApp1
|
||||
{
|
||||
public partial class Main : Form
|
||||
@@ -40,12 +41,17 @@ namespace WindowsFormsApp1
|
||||
public Main()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public string User_Name { get; internal set; }
|
||||
|
||||
private void Main_Load(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
|
||||
|
||||
this.Visible = false; // 메인폼을 먼저 숨김
|
||||
|
||||
#region "Log setting"
|
||||
@@ -102,6 +108,8 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#region 즐겨찾기 버튼 세팅
|
||||
public void SetBtnName()
|
||||
{
|
||||
|
||||
@@ -18,9 +18,15 @@ namespace WindowsFormsApp1
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
DB_InitSetting();
|
||||
UpdaterCheck();
|
||||
|
||||
Application.Run(new Main());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// factory client update checkd
|
||||
/// </summary>
|
||||
|
||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
|
||||
// 기본값으로 할 수 있습니다.
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.185")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.185")]
|
||||
[assembly: AssemblyVersion("1.0.0.186")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.186")]
|
||||
|
||||
82
unimarc/unimarc/SearchModel/BookSearchService.cs
Normal file
82
unimarc/unimarc/SearchModel/BookSearchService.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace BokBonCheck
|
||||
{
|
||||
public class BookSearchResult
|
||||
{
|
||||
public string SiteName { get; set; }
|
||||
public int BookCount { get; set; }
|
||||
public string SearchTerm { get; set; }
|
||||
public DateTime SearchTime { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
public bool IsSuccess { get; set; }
|
||||
}
|
||||
|
||||
public class BookSearchService
|
||||
{
|
||||
private readonly List<ILibrarySearcher> _searchers;
|
||||
|
||||
public BookSearchService()
|
||||
{
|
||||
_searchers = new List<ILibrarySearcher>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<List<BookSearchResult>> SearchBooksAsync(string searchTerm)
|
||||
{
|
||||
var results = new List<BookSearchResult>();
|
||||
|
||||
foreach (var searcher in _searchers)
|
||||
{
|
||||
searcher.StartDriver();
|
||||
var result = await searcher.SearchAsync(searchTerm);
|
||||
results.Add(result);
|
||||
//searcher.StopDriver();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return Searcher
|
||||
/// </summary>
|
||||
/// <param name="no"></param>
|
||||
/// <returns></returns>
|
||||
public ILibrarySearcher Get(int no)
|
||||
{
|
||||
return _searchers.Where(t => t.No == no).FirstOrDefault();
|
||||
}
|
||||
public void AddSearcher(ILibrarySearcher searcher)
|
||||
{
|
||||
if (!_searchers.Any(s => s.SiteName == searcher.SiteName))
|
||||
{
|
||||
_searchers.Add(searcher);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveSearcher(string siteName)
|
||||
{
|
||||
var searcher = _searchers.FirstOrDefault(s => s.SiteName == siteName);
|
||||
if (searcher != null)
|
||||
{
|
||||
_searchers.Remove(searcher);
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> GetAvailableSites()
|
||||
{
|
||||
return _searchers.Select(s => s.SiteName).ToList();
|
||||
}
|
||||
|
||||
public void ClearSearchers()
|
||||
{
|
||||
_searchers.Clear();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
378
unimarc/unimarc/SearchModel/ChromeDriverManager.cs
Normal file
378
unimarc/unimarc/SearchModel/ChromeDriverManager.cs
Normal file
@@ -0,0 +1,378 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using WebDriverManager;
|
||||
using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.Reflection;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace BokBonCheck
|
||||
{
|
||||
public static class ChromeDriverManager
|
||||
{
|
||||
private static string _driverPath = null;
|
||||
|
||||
public static async Task<string> SetupChromeDriverAsync(DownloadProgressForm progressForm = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Chrome 버전 확인
|
||||
var chromeVersion = GetChromeVersion();
|
||||
Console.WriteLine($"설치된 Chrome 버전: {chromeVersion}");
|
||||
|
||||
if (progressForm != null)
|
||||
{
|
||||
progressForm.UpdateProgress(10, $"Chrome 버전 확인 중... ({chromeVersion})");
|
||||
}
|
||||
|
||||
// 기존 드라이버 경로 확인
|
||||
var existingDriverPath = GetExistingDriverPath();
|
||||
if (!string.IsNullOrEmpty(existingDriverPath) && File.Exists(existingDriverPath))
|
||||
{
|
||||
Console.WriteLine($"기존 드라이버 발견: {existingDriverPath}");
|
||||
|
||||
// 기존 드라이버 테스트
|
||||
if (await TestExistingDriver(existingDriverPath))
|
||||
{
|
||||
if (progressForm != null)
|
||||
{
|
||||
progressForm.UpdateProgress(100, "기존 드라이버 사용");
|
||||
progressForm.SetCompleted("기존 드라이버를 사용합니다.");
|
||||
}
|
||||
|
||||
_driverPath = existingDriverPath;
|
||||
Environment.SetEnvironmentVariable("webdriver.chrome.driver", existingDriverPath);
|
||||
return existingDriverPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("기존 드라이버 테스트 실패 - 새로 다운로드");
|
||||
// 기존 드라이버가 작동하지 않으면 삭제
|
||||
try
|
||||
{
|
||||
File.Delete(existingDriverPath);
|
||||
Console.WriteLine("기존 드라이버 삭제됨");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"기존 드라이버 삭제 실패: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (progressForm != null)
|
||||
{
|
||||
progressForm.UpdateProgress(30, "Chrome 버전에 맞는 드라이버 다운로드 중...");
|
||||
}
|
||||
|
||||
// WebDriverManager를 사용하여 설치된 Chrome 버전에 맞는 드라이버 다운로드
|
||||
var driverManager = new DriverManager();
|
||||
var driverPath = driverManager.SetUpDriver(new ChromeConfig(), "MatchingBrowser");
|
||||
|
||||
// 다운로드된 드라이버 경로 저장
|
||||
_driverPath = driverPath;
|
||||
|
||||
// 환경 변수 설정
|
||||
Environment.SetEnvironmentVariable("webdriver.chrome.driver", driverPath);
|
||||
|
||||
if (progressForm != null)
|
||||
{
|
||||
progressForm.UpdateProgress(100, "드라이버 다운로드 완료");
|
||||
progressForm.SetCompleted("드라이버 다운로드 완료!");
|
||||
}
|
||||
|
||||
Console.WriteLine($"ChromeDriver 경로: {driverPath}");
|
||||
Console.WriteLine($"환경 변수 설정: webdriver.chrome.driver = {driverPath}");
|
||||
|
||||
return driverPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ChromeDriver 설정 오류: {ex.Message}");
|
||||
if (progressForm != null)
|
||||
{
|
||||
progressForm.SetError($"설정 오류: {ex.Message}");
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetExistingDriverPath()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 환경 변수에서 확인
|
||||
var envPath = Environment.GetEnvironmentVariable("webdriver.chrome.driver");
|
||||
if (!string.IsNullOrEmpty(envPath) && File.Exists(envPath))
|
||||
{
|
||||
return envPath;
|
||||
}
|
||||
|
||||
// WebDriverManager 캐시 폴더에서 확인
|
||||
var cachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
|
||||
".cache", "selenium");
|
||||
if (Directory.Exists(cachePath))
|
||||
{
|
||||
var chromeDriverFiles = Directory.GetFiles(cachePath, "chromedriver*", SearchOption.AllDirectories);
|
||||
foreach (var file in chromeDriverFiles)
|
||||
{
|
||||
if (file.EndsWith(".exe") || !Path.HasExtension(file))
|
||||
{
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetDriverPath()
|
||||
{
|
||||
return _driverPath;
|
||||
}
|
||||
|
||||
private static string GetChromeVersion()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Windows에서 Chrome 설치 경로 확인
|
||||
var chromePaths = new[]
|
||||
{
|
||||
@"C:\Program Files\Google\Chrome\Application\chrome.exe",
|
||||
@"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
@"Google\Chrome\Application\chrome.exe")
|
||||
};
|
||||
|
||||
foreach (var path in chromePaths)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var versionInfo = FileVersionInfo.GetVersionInfo(path);
|
||||
var version = versionInfo.FileVersion;
|
||||
Console.WriteLine($"Chrome 버전 감지: {version} (경로: {path})");
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
return "알 수 없음";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Chrome 버전 감지 실패: {ex.Message}");
|
||||
return "확인 실패";
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsChromeInstalled()
|
||||
{
|
||||
try
|
||||
{
|
||||
var chromePaths = new[]
|
||||
{
|
||||
@"C:\Program Files\Google\Chrome\Application\chrome.exe",
|
||||
@"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
@"Google\Chrome\Application\chrome.exe")
|
||||
};
|
||||
|
||||
foreach (var path in chromePaths)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<bool> TestChromeDriverAsync(DownloadProgressForm progressForm = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var driverPath = await SetupChromeDriverAsync(progressForm);
|
||||
|
||||
if (progressForm != null)
|
||||
{
|
||||
progressForm.UpdateProgress(50, "드라이버 테스트 중...");
|
||||
}
|
||||
|
||||
// ChromeDriver 서비스 설정
|
||||
var service = OpenQA.Selenium.Chrome.ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(driverPath));
|
||||
service.HideCommandPromptWindow = true;
|
||||
// 간단한 테스트 실행
|
||||
var options = new OpenQA.Selenium.Chrome.ChromeOptions();
|
||||
options.AddArgument("--headless");
|
||||
options.AddArgument("--no-sandbox");
|
||||
options.AddArgument("--disable-dev-shm-usage");
|
||||
options.AddArgument("--disable-gpu");
|
||||
options.AddArgument("--remote-debugging-port=0");
|
||||
|
||||
using (var driver = new OpenQA.Selenium.Chrome.ChromeDriver(service, options))
|
||||
{
|
||||
driver.Navigate().GoToUrl("https://www.google.com");
|
||||
var title = driver.Title;
|
||||
|
||||
Console.WriteLine($"드라이버 테스트 성공: {title}");
|
||||
|
||||
if (progressForm != null)
|
||||
{
|
||||
progressForm.UpdateProgress(100, "드라이버 테스트 성공!");
|
||||
progressForm.SetCompleted("드라이버 테스트 성공!");
|
||||
}
|
||||
|
||||
return !string.IsNullOrEmpty(title);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ChromeDriver 테스트 실패: {ex.Message}");
|
||||
if (progressForm != null)
|
||||
{
|
||||
progressForm.SetError($"테스트 실패: {ex.Message}");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ClearDriverCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Chrome 드라이버 캐시 정리 시작...");
|
||||
|
||||
// WebDriverManager 캐시 폴더 정리
|
||||
var cachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
|
||||
".cache", "selenium");
|
||||
if (Directory.Exists(cachePath))
|
||||
{
|
||||
Directory.Delete(cachePath, true);
|
||||
Console.WriteLine($"WebDriverManager 캐시 정리됨: {cachePath}");
|
||||
}
|
||||
|
||||
// 환경 변수에서 설정된 드라이버 경로도 정리
|
||||
var envDriverPath = Environment.GetEnvironmentVariable("webdriver.chrome.driver");
|
||||
if (!string.IsNullOrEmpty(envDriverPath) && File.Exists(envDriverPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(envDriverPath);
|
||||
Console.WriteLine($"환경 변수 드라이버 삭제됨: {envDriverPath}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"환경 변수 드라이버 삭제 실패: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// 저장된 드라이버 경로도 정리
|
||||
if (!string.IsNullOrEmpty(_driverPath) && File.Exists(_driverPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(_driverPath);
|
||||
Console.WriteLine($"저장된 드라이버 삭제됨: {_driverPath}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"저장된 드라이버 삭제 실패: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
_driverPath = null;
|
||||
Environment.SetEnvironmentVariable("webdriver.chrome.driver", null);
|
||||
|
||||
Console.WriteLine("Chrome 드라이버 캐시 정리 완료");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"캐시 정리 실패: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsDriverReady()
|
||||
{
|
||||
try
|
||||
{
|
||||
var driverPath = GetExistingDriverPath();
|
||||
if (string.IsNullOrEmpty(driverPath) || !File.Exists(driverPath))
|
||||
{
|
||||
Console.WriteLine("기존 드라이버가 없습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Console.WriteLine($"드라이버 준비 상태 확인: {driverPath}");
|
||||
|
||||
// 간단한 테스트 실행
|
||||
var service = OpenQA.Selenium.Chrome.ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(driverPath));
|
||||
service.HideCommandPromptWindow = true;
|
||||
var options = new OpenQA.Selenium.Chrome.ChromeOptions();
|
||||
options.AddArgument("--headless");
|
||||
options.AddArgument("--no-sandbox");
|
||||
options.AddArgument("--disable-dev-shm-usage");
|
||||
options.AddArgument("--disable-gpu");
|
||||
options.AddArgument("--remote-debugging-port=0");
|
||||
|
||||
using (var driver = new OpenQA.Selenium.Chrome.ChromeDriver(service, options))
|
||||
{
|
||||
driver.Navigate().GoToUrl("https://www.google.com");
|
||||
var result = !string.IsNullOrEmpty(driver.Title);
|
||||
Console.WriteLine($"드라이버 준비 상태: {(result ? "준비됨" : "실패")}");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"드라이버 준비 상태 확인 실패: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<bool> TestExistingDriver(string driverPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"기존 드라이버 테스트: {driverPath}");
|
||||
|
||||
// ChromeDriver 서비스 설정
|
||||
var service = OpenQA.Selenium.Chrome.ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(driverPath));
|
||||
service.HideCommandPromptWindow = true;
|
||||
|
||||
// 간단한 테스트 실행
|
||||
var options = new OpenQA.Selenium.Chrome.ChromeOptions();
|
||||
options.AddArgument("--headless");
|
||||
options.AddArgument("--no-sandbox");
|
||||
options.AddArgument("--disable-dev-shm-usage");
|
||||
options.AddArgument("--disable-gpu");
|
||||
options.AddArgument("--remote-debugging-port=0");
|
||||
|
||||
using (var driver = new OpenQA.Selenium.Chrome.ChromeDriver(service, options))
|
||||
{
|
||||
driver.Navigate().GoToUrl("https://www.google.com");
|
||||
var title = driver.Title;
|
||||
Console.WriteLine($"드라이버 테스트 성공: {title}");
|
||||
return !string.IsNullOrEmpty(title);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"기존 드라이버 테스트 실패: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
142
unimarc/unimarc/SearchModel/DownloadProgressForm.cs
Normal file
142
unimarc/unimarc/SearchModel/DownloadProgressForm.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BokBonCheck
|
||||
{
|
||||
public partial class DownloadProgressForm : Form
|
||||
{
|
||||
private ProgressBar progressBar;
|
||||
private Label lblStatus;
|
||||
private Label lblProgress;
|
||||
private Button btnCancel;
|
||||
private bool isCancelled = false;
|
||||
|
||||
public DownloadProgressForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.StartPosition = FormStartPosition.CenterScreen;
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.Text = "Chrome 드라이버 다운로드";
|
||||
this.Size = new Size(400, 150);
|
||||
this.StartPosition = FormStartPosition.CenterParent;
|
||||
this.FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.ControlBox = false;
|
||||
this.TopMost = true;
|
||||
|
||||
// 상태 라벨
|
||||
lblStatus = new Label
|
||||
{
|
||||
Text = "Chrome 드라이버를 확인하고 있습니다...",
|
||||
Location = new Point(20, 20),
|
||||
Size = new Size(360, 20),
|
||||
Font = new Font("맑은 고딕", 9),
|
||||
TextAlign = ContentAlignment.MiddleCenter
|
||||
};
|
||||
|
||||
// 진행률 라벨
|
||||
lblProgress = new Label
|
||||
{
|
||||
Text = "0%",
|
||||
Location = new Point(20, 50),
|
||||
Size = new Size(360, 20),
|
||||
Font = new Font("맑은 고딕", 10, FontStyle.Bold),
|
||||
TextAlign = ContentAlignment.MiddleCenter,
|
||||
ForeColor = Color.Blue
|
||||
};
|
||||
|
||||
// 프로그레스 바
|
||||
progressBar = new ProgressBar
|
||||
{
|
||||
Location = new Point(20, 80),
|
||||
Size = new Size(360, 25),
|
||||
Style = ProgressBarStyle.Continuous,
|
||||
Minimum = 0,
|
||||
Maximum = 100,
|
||||
Value = 0
|
||||
};
|
||||
|
||||
// 취소 버튼
|
||||
btnCancel = new Button
|
||||
{
|
||||
Text = "취소",
|
||||
Location = new Point(150, 115),
|
||||
Size = new Size(100, 30),
|
||||
Font = new Font("맑은 고딕", 9),
|
||||
BackColor = Color.LightCoral
|
||||
};
|
||||
|
||||
btnCancel.Click += BtnCancel_Click;
|
||||
|
||||
// 컨트롤 추가
|
||||
this.Controls.AddRange(new Control[]
|
||||
{
|
||||
lblStatus, lblProgress, progressBar, btnCancel
|
||||
});
|
||||
}
|
||||
|
||||
private void BtnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
isCancelled = true;
|
||||
btnCancel.Enabled = false;
|
||||
lblStatus.Text = "취소 중...";
|
||||
}
|
||||
|
||||
public bool IsCancelled => isCancelled;
|
||||
|
||||
public void UpdateProgress(int percentage, string status = null)
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
{
|
||||
this.Invoke(new Action<int, string>(UpdateProgress), percentage, status);
|
||||
return;
|
||||
}
|
||||
|
||||
progressBar.Value = Math.Min(percentage, 100);
|
||||
lblProgress.Text = $"{percentage}%";
|
||||
|
||||
if (!string.IsNullOrEmpty(status))
|
||||
{
|
||||
lblStatus.Text = status;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCompleted(string message = "다운로드 완료!")
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
{
|
||||
this.Invoke(new Action<string>(SetCompleted), message);
|
||||
return;
|
||||
}
|
||||
|
||||
progressBar.Value = 100;
|
||||
lblProgress.Text = "100%";
|
||||
lblStatus.Text = message;
|
||||
btnCancel.Text = "확인";
|
||||
btnCancel.BackColor = Color.LightGreen;
|
||||
btnCancel.Enabled = true;
|
||||
}
|
||||
|
||||
public void SetError(string errorMessage)
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
{
|
||||
this.Invoke(new Action<string>(SetError), errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
lblStatus.Text = "오류 발생";
|
||||
lblProgress.Text = "실패";
|
||||
lblProgress.ForeColor = Color.Red;
|
||||
btnCancel.Text = "확인";
|
||||
btnCancel.BackColor = Color.LightCoral;
|
||||
btnCancel.Enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
unimarc/unimarc/SearchModel/ILibrarySearcher.cs
Normal file
17
unimarc/unimarc/SearchModel/ILibrarySearcher.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BokBonCheck
|
||||
{
|
||||
public interface ILibrarySearcher
|
||||
{
|
||||
int No { get; set; }
|
||||
string SiteName { get; }
|
||||
string SiteUrl { get; }
|
||||
Task<BookSearchResult> SearchAsync(string searchTerm);
|
||||
void StartDriver();
|
||||
void StopDriver();
|
||||
|
||||
Task WaitForPageChange(WebDriverWait wait);
|
||||
}
|
||||
}
|
||||
321
unimarc/unimarc/SearchModel/KwangjuCityLibrarySearcher.cs
Normal file
321
unimarc/unimarc/SearchModel/KwangjuCityLibrarySearcher.cs
Normal file
@@ -0,0 +1,321 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Chrome;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
using System.Text.RegularExpressions;
|
||||
using WebDriverManager;
|
||||
using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace BokBonCheck
|
||||
{
|
||||
public class KwangjuCityLibrarySearcher_choisangjun : KwangjuCityLibrarySearcher
|
||||
{
|
||||
public KwangjuCityLibrarySearcher_choisangjun(int no) : base(no)
|
||||
{
|
||||
SelectorValue = "MF";
|
||||
SiteName = "광주시교육청통합도서관(분관최상준도서관)";
|
||||
}
|
||||
}
|
||||
public class KwangjuCityLibrarySearcher_dagachi : KwangjuCityLibrarySearcher
|
||||
{
|
||||
public KwangjuCityLibrarySearcher_dagachi(int no) : base(no)
|
||||
{
|
||||
SelectorValue = "ME";
|
||||
SiteName = "광주시교육청통합도서관(송정다가치문화도서관)";
|
||||
}
|
||||
}
|
||||
public class KwangjuCityLibrarySearcher_central : KwangjuCityLibrarySearcher
|
||||
{
|
||||
public KwangjuCityLibrarySearcher_central(int no) : base(no)
|
||||
{
|
||||
SelectorValue = "MD";
|
||||
SiteName = "광주시교육청통합도서관(중앙도서관)";
|
||||
}
|
||||
}
|
||||
public class KwangjuCityLibrarySearcher_Student : KwangjuCityLibrarySearcher
|
||||
{
|
||||
public KwangjuCityLibrarySearcher_Student(int no) : base(no)
|
||||
{
|
||||
SelectorValue = "MC";
|
||||
SiteName = "광주시교육청통합도서관(학생교육문화회관)";
|
||||
}
|
||||
}
|
||||
public class KwangjuCityLibrarySearcher_Kumho : KwangjuCityLibrarySearcher
|
||||
{
|
||||
public KwangjuCityLibrarySearcher_Kumho(int no) : base(no)
|
||||
{
|
||||
SelectorValue = "MB";
|
||||
SiteName = "광주시교육청통합도서관(금호평생교육관)";
|
||||
}
|
||||
}
|
||||
public class KwangjuCityLibrarySearcher_Indi : KwangjuCityLibrarySearcher
|
||||
{
|
||||
public KwangjuCityLibrarySearcher_Indi(int no) : base(no)
|
||||
{
|
||||
SelectorValue = "MA";
|
||||
SiteName = "광주시교육청통합도서관(학생독립운동기념회관)";
|
||||
}
|
||||
}
|
||||
public abstract class KwangjuCityLibrarySearcher : ILibrarySearcher
|
||||
{
|
||||
public int No { get; set; }
|
||||
public string SiteName { get; protected set; } = "광주시교육청통합도서관";
|
||||
public string SiteUrl => "https://lib.gen.go.kr/main/site/search/bookSearch.do#simple";
|
||||
|
||||
protected string SelectorValue = "";
|
||||
|
||||
private ChromeDriver _driver;
|
||||
private ChromeDriverService _service;
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
private const int SW_MINIMIZE = 6;
|
||||
|
||||
public KwangjuCityLibrarySearcher(int no)
|
||||
{
|
||||
this.No = no;
|
||||
}
|
||||
|
||||
public void StartDriver()
|
||||
{
|
||||
if (_driver == null)
|
||||
{
|
||||
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=1920,1080");
|
||||
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})");
|
||||
}
|
||||
}
|
||||
|
||||
public void StopDriver()
|
||||
{
|
||||
if (_driver != null)
|
||||
{
|
||||
_driver.Quit();
|
||||
_driver.Dispose();
|
||||
_driver = null;
|
||||
}
|
||||
if (_service != null)
|
||||
{
|
||||
_service.Dispose();
|
||||
_service = null;
|
||||
}
|
||||
}
|
||||
|
||||
virtual protected void SelectLibrary(WebDriverWait wait)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 콤보박스(select) 요소 찾기
|
||||
var selectElement = wait.Until(d => d.FindElement(By.CssSelector("#manage_code")));
|
||||
var select = new OpenQA.Selenium.Support.UI.SelectElement(selectElement);
|
||||
|
||||
// value가 "MA"인 옵션 선택
|
||||
select.SelectByValue(SelectorValue);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 예외 처리 (필요시 로깅 등)
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<BookSearchResult> SearchAsync(string searchTerm)
|
||||
{
|
||||
var result = new BookSearchResult
|
||||
{
|
||||
SiteName = SiteName,
|
||||
SearchTerm = searchTerm,
|
||||
SearchTime = DateTime.Now
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
if (_driver == null)
|
||||
throw new InvalidOperationException("드라이버가 시작되지 않았습니다. StartDriver()를 먼저 호출하세요.");
|
||||
|
||||
_driver.Navigate().GoToUrl(SiteUrl);
|
||||
|
||||
// 페이지 로딩 대기
|
||||
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(15));
|
||||
|
||||
// 모든 감지 방법이 끝나면 크롬창 최소화
|
||||
IntPtr chromeWindow = FindWindow("Chrome_WidgetWin_1", null);
|
||||
if (chromeWindow != IntPtr.Zero)
|
||||
{
|
||||
ShowWindow(chromeWindow, SW_MINIMIZE);
|
||||
}
|
||||
|
||||
//대상도서관 선택
|
||||
SelectLibrary(wait);
|
||||
|
||||
// 검색창 찾기
|
||||
IWebElement searchBox = null;
|
||||
try
|
||||
{
|
||||
// 여러 가능한 선택자 시도
|
||||
var selectors = new[]
|
||||
{
|
||||
"input[id='search_txt']",
|
||||
"input[type='text']",
|
||||
};
|
||||
|
||||
foreach (var selector in selectors)
|
||||
{
|
||||
try
|
||||
{
|
||||
searchBox = wait.Until(d =>
|
||||
{
|
||||
var el = d.FindElement(By.CssSelector(selector));
|
||||
return (el != null && el.Displayed && el.Enabled) ? el : null;
|
||||
});
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (searchBox == null)
|
||||
{
|
||||
throw new Exception("검색창을 찾을 수 없습니다.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"검색창 찾기 실패: {ex.Message}");
|
||||
}
|
||||
|
||||
// 혹시 readonly라면 속성 제거
|
||||
((IJavaScriptExecutor)_driver).ExecuteScript("arguments[0].removeAttribute('readonly')", searchBox);
|
||||
|
||||
// 입력 전 clear
|
||||
searchBox.Clear();
|
||||
searchBox.SendKeys(searchTerm);
|
||||
|
||||
// 검색 버튼 클릭
|
||||
IWebElement searchButton = null;
|
||||
try
|
||||
{
|
||||
var buttonSelectors = new[]
|
||||
{
|
||||
"input[type='submit']",
|
||||
};
|
||||
foreach (var selector in buttonSelectors)
|
||||
{
|
||||
try
|
||||
{
|
||||
searchButton = _driver.FindElement(By.CssSelector(selector));
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (searchButton == null)
|
||||
{
|
||||
// Enter 키로 검색 시도
|
||||
searchBox.SendKeys(Keys.Enter);
|
||||
}
|
||||
else
|
||||
{
|
||||
searchButton.Click();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Enter 키로 검색 시도
|
||||
searchBox.SendKeys(Keys.Enter);
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver);
|
||||
|
||||
result.BookCount = resultCount;
|
||||
result.IsSuccess = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.IsSuccess = false;
|
||||
result.ErrorMessage = ex.Message;
|
||||
result.BookCount = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver)
|
||||
{
|
||||
try
|
||||
{
|
||||
// div.search-result 내부의 span에서 '전체 N' 텍스트 추출
|
||||
var resultDiv = driver.FindElement(By.CssSelector("div.ndls_result"));
|
||||
var span = resultDiv.FindElement(By.XPath(".//span[contains(text(),'전체')]"));
|
||||
string text = span.Text; // 예: "전체 5 "
|
||||
var match = System.Text.RegularExpressions.Regex.Match(text, @"전체\s*(\d+)");
|
||||
if (match.Success)
|
||||
{
|
||||
return int.Parse(match.Groups[1].Value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
public async Task WaitForPageChange(WebDriverWait wait)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 방법 4: 페이지 로딩 상태 확인
|
||||
wait.Until(d =>
|
||||
{
|
||||
var readyState = ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState");
|
||||
return readyState.Equals("complete");
|
||||
});
|
||||
|
||||
// 방법 5: 특정 텍스트가 페이지에 나타날 때까지 대기
|
||||
wait.Until(d =>
|
||||
{
|
||||
var pageText = d.FindElement(By.TagName("body")).Text;
|
||||
return pageText.Contains("전체") || pageText.Contains("건") || pageText.Contains("검색결과");
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 모든 감지 방법이 실패하면 최소한의 대기 시간 적용
|
||||
await Task.Delay(2000);
|
||||
throw new Exception($"페이지 변경 감지 실패: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
441
unimarc/unimarc/SearchModel/NamguLibrarySearcher.cs
Normal file
441
unimarc/unimarc/SearchModel/NamguLibrarySearcher.cs
Normal file
@@ -0,0 +1,441 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Chrome;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
using System.Text.RegularExpressions;
|
||||
using WebDriverManager;
|
||||
using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace BokBonCheck
|
||||
{
|
||||
public class NamguLibrarySearcher_Munhwa : NamguLibrarySearcher
|
||||
{
|
||||
public NamguLibrarySearcher_Munhwa(int no) : base(no)
|
||||
{
|
||||
SiteName = "남구통합도서관(문화정보도서관)"; // 문화관 검색기
|
||||
}
|
||||
|
||||
protected override void SelectLibrary(WebDriverWait wait)
|
||||
{
|
||||
IWebElement searchBox = null;
|
||||
try
|
||||
{
|
||||
var selector = "#clickAll";
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
if (searchBox != null && searchBox.Selected == true)
|
||||
{
|
||||
searchBox.Click(); // 전체체크박스가 체크되어 있으면 클릭해서 해제
|
||||
}
|
||||
else return;
|
||||
|
||||
selector = "#libMA";
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
if (searchBox != null && searchBox.Selected == false)
|
||||
{
|
||||
searchBox.Click(); // 문화관 체크박스 선택
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
public class NamguLibrarySearcher_Purungil : NamguLibrarySearcher
|
||||
{
|
||||
public NamguLibrarySearcher_Purungil(int no) : base(no)
|
||||
{
|
||||
SiteName = "남구통합도서관(푸른길도서관)";
|
||||
}
|
||||
|
||||
protected override void SelectLibrary(WebDriverWait wait)
|
||||
{
|
||||
IWebElement searchBox = null;
|
||||
try
|
||||
{
|
||||
var selector = "#clickAll";
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
if (searchBox != null && searchBox.Selected == true)
|
||||
{
|
||||
searchBox.Click(); // 전체체크박스가 체크되어 있으면 클릭해서 해제
|
||||
}
|
||||
else return;
|
||||
|
||||
selector = "#libMB";
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
if (searchBox != null && searchBox.Selected == false)
|
||||
{
|
||||
searchBox.Click(); // 체크박스 선택
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
public class NamguLibrarySearcher_Children : NamguLibrarySearcher
|
||||
{
|
||||
public NamguLibrarySearcher_Children(int no) : base(no)
|
||||
{
|
||||
SiteName = "남구통합도서관(청소년도서관)";
|
||||
}
|
||||
|
||||
protected override void SelectLibrary(WebDriverWait wait)
|
||||
{
|
||||
IWebElement searchBox = null;
|
||||
try
|
||||
{
|
||||
var selector = "#clickAll";
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
if (searchBox != null && searchBox.Selected == true)
|
||||
{
|
||||
searchBox.Click(); // 전체체크박스가 체크되어 있으면 클릭해서 해제
|
||||
}
|
||||
else return;
|
||||
|
||||
selector = "#libMC";
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
if (searchBox != null && searchBox.Selected == false)
|
||||
{
|
||||
searchBox.Click(); // 체크박스 선택
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
public class NamguLibrarySearcher_Hyocheon : NamguLibrarySearcher
|
||||
{
|
||||
public NamguLibrarySearcher_Hyocheon(int no) : base(no)
|
||||
{
|
||||
SiteName = "남구통합도서관(효천어울림도서관)";
|
||||
}
|
||||
|
||||
protected override void SelectLibrary(WebDriverWait wait)
|
||||
{
|
||||
IWebElement searchBox = null;
|
||||
try
|
||||
{
|
||||
var selector = "#clickAll";
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
if (searchBox != null && searchBox.Selected == true)
|
||||
{
|
||||
searchBox.Click(); // 전체체크박스가 체크되어 있으면 클릭해서 해제
|
||||
}
|
||||
else return;
|
||||
|
||||
selector = "#libSW";
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
if (searchBox != null && searchBox.Selected == false)
|
||||
{
|
||||
searchBox.Click(); // 체크박스 선택
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
public class NamguLibrarySearcher_Smart : NamguLibrarySearcher
|
||||
{
|
||||
public NamguLibrarySearcher_Smart(int no) : base(no)
|
||||
{
|
||||
SiteName = "남구통합도서관(스마트도서관)";
|
||||
}
|
||||
|
||||
protected override void SelectLibrary(WebDriverWait wait)
|
||||
{
|
||||
IWebElement searchBox = null;
|
||||
try
|
||||
{
|
||||
var selector = "#clickAll";
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
if (searchBox != null && searchBox.Selected == true)
|
||||
{
|
||||
searchBox.Click(); // 전체체크박스가 체크되어 있으면 클릭해서 해제
|
||||
}
|
||||
else return;
|
||||
|
||||
selector = "#libSQ";
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
if (searchBox != null && searchBox.Selected == false)
|
||||
{
|
||||
searchBox.Click(); // 체크박스 선택
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
public class NamguLibrarySearcher : ILibrarySearcher
|
||||
{
|
||||
public string SiteName { get; protected set; } = "남구통합도서관(전체)";
|
||||
public string SiteUrl => "https://lib.namgu.gwangju.kr/main/bookSearch";
|
||||
|
||||
public int No { get; set; }
|
||||
|
||||
private ChromeDriver _driver;
|
||||
private ChromeDriverService _service;
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
private const int SW_MINIMIZE = 6;
|
||||
|
||||
public NamguLibrarySearcher(int no)
|
||||
{
|
||||
this.No = no;
|
||||
}
|
||||
|
||||
public void StartDriver()
|
||||
{
|
||||
if (_driver == null)
|
||||
{
|
||||
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=1920,1080");
|
||||
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})");
|
||||
}
|
||||
}
|
||||
|
||||
public void StopDriver()
|
||||
{
|
||||
if (_driver != null)
|
||||
{
|
||||
_driver.Quit();
|
||||
_driver.Dispose();
|
||||
_driver = null;
|
||||
}
|
||||
if (_service != null)
|
||||
{
|
||||
_service.Dispose();
|
||||
_service = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual protected void SelectLibrary(WebDriverWait wait)
|
||||
{
|
||||
IWebElement searchBox = null;
|
||||
try
|
||||
{
|
||||
var selector = "#clickAll";
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
if (searchBox != null && searchBox.Selected == false)
|
||||
{
|
||||
searchBox.Click(); // 전체체크박스가 해제되어 있으면 클릭해서 선택
|
||||
}
|
||||
else return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<BookSearchResult> SearchAsync(string searchTerm)
|
||||
{
|
||||
var result = new BookSearchResult
|
||||
{
|
||||
SiteName = SiteName,
|
||||
SearchTerm = searchTerm,
|
||||
SearchTime = DateTime.Now
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
if (_driver == null)
|
||||
throw new InvalidOperationException("드라이버가 시작되지 않았습니다. StartDriver()를 먼저 호출하세요.");
|
||||
|
||||
_driver.Navigate().GoToUrl(SiteUrl);
|
||||
|
||||
// 페이지 로딩 대기
|
||||
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(15));
|
||||
|
||||
// 모든 감지 방법이 끝나면 크롬창 최소화
|
||||
IntPtr chromeWindow = FindWindow("Chrome_WidgetWin_1", null);
|
||||
if (chromeWindow != IntPtr.Zero)
|
||||
{
|
||||
ShowWindow(chromeWindow, SW_MINIMIZE);
|
||||
}
|
||||
|
||||
//대상도서관 선택
|
||||
SelectLibrary(wait);
|
||||
|
||||
// 검색창 찾기 (남구통합도서관 사이트의 특정 선택자 사용)
|
||||
IWebElement searchBox = null;
|
||||
try
|
||||
{
|
||||
// 여러 가능한 선택자 시도
|
||||
var selectors = new[]
|
||||
{
|
||||
"input[name='query']",
|
||||
"input[id='query']",
|
||||
"input[type='text']",
|
||||
};
|
||||
|
||||
foreach (var selector in selectors)
|
||||
{
|
||||
try
|
||||
{
|
||||
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (searchBox == null)
|
||||
{
|
||||
throw new Exception("검색창을 찾을 수 없습니다.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"검색창 찾기 실패: {ex.Message}");
|
||||
}
|
||||
|
||||
// 검색어 입력
|
||||
searchBox.Clear();
|
||||
searchBox.SendKeys(searchTerm);
|
||||
|
||||
// 검색 버튼 클릭
|
||||
IWebElement searchButton = null;
|
||||
try
|
||||
{
|
||||
var buttonSelectors = new[]
|
||||
{
|
||||
"button[type='submit']",
|
||||
"input[type='submit']",
|
||||
".search-btn",
|
||||
".btn-search",
|
||||
"button:contains('검색')",
|
||||
"input[value*='검색']",
|
||||
"button[class*='search']",
|
||||
"input[class*='search']"
|
||||
};
|
||||
|
||||
foreach (var selector in buttonSelectors)
|
||||
{
|
||||
try
|
||||
{
|
||||
searchButton = _driver.FindElement(By.CssSelector(selector));
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (searchButton == null)
|
||||
{
|
||||
// Enter 키로 검색 시도
|
||||
searchBox.SendKeys(Keys.Enter);
|
||||
}
|
||||
else
|
||||
{
|
||||
searchButton.Click();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Enter 키로 검색 시도
|
||||
searchBox.SendKeys(Keys.Enter);
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver);
|
||||
|
||||
result.BookCount = resultCount;
|
||||
result.IsSuccess = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.IsSuccess = false;
|
||||
result.ErrorMessage = ex.Message;
|
||||
result.BookCount = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver)
|
||||
{
|
||||
try
|
||||
{
|
||||
// div.search-result 내부의 span에서 '전체 N' 텍스트 추출
|
||||
var resultDiv = driver.FindElement(By.CssSelector("div.search-result"));
|
||||
var span = resultDiv.FindElement(By.XPath(".//span[contains(text(),'전체')]"));
|
||||
string text = span.Text; // 예: "전체 5 "
|
||||
var match = System.Text.RegularExpressions.Regex.Match(text, @"전체\s*(\d+)");
|
||||
if (match.Success)
|
||||
{
|
||||
return int.Parse(match.Groups[1].Value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
public async Task WaitForPageChange(WebDriverWait wait)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 방법 4: 페이지 로딩 상태 확인
|
||||
wait.Until(d =>
|
||||
{
|
||||
var readyState = ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState");
|
||||
return readyState.Equals("complete");
|
||||
});
|
||||
|
||||
// 방법 5: 특정 텍스트가 페이지에 나타날 때까지 대기
|
||||
wait.Until(d =>
|
||||
{
|
||||
var pageText = d.FindElement(By.TagName("body")).Text;
|
||||
return pageText.Contains("전체") || pageText.Contains("건") || pageText.Contains("검색결과");
|
||||
});
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 모든 감지 방법이 실패하면 최소한의 대기 시간 적용
|
||||
await Task.Delay(2000);
|
||||
throw new Exception($"페이지 변경 감지 실패: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,6 +75,9 @@
|
||||
<ManifestKeyFile>UniMarc_TemporaryKey.pfx</ManifestKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="AngleSharp, Version=1.0.4.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\AngleSharp.1.0.4\lib\net472\AngleSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="arCommUtil">
|
||||
<HintPath>..\dll\arCommUtil.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -87,19 +90,62 @@
|
||||
<Reference Include="CarlosAg.ExcelXmlWriter">
|
||||
<HintPath>..\dll\CarlosAg.ExcelXmlWriter.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ICSharpCode.SharpZipLib, Version=1.4.2.13, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpZipLib.1.4.2\lib\netstandard2.0\ICSharpCode.SharpZipLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="Microsoft.Win32.Registry, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Win32.Registry.5.0.0\lib\net461\Microsoft.Win32.Registry.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=8.0.21.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL" />
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Renci.SshNet, Version=2020.0.1.0, Culture=neutral, PublicKeyToken=1cee9f8bde3db106, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SSH.NET.2020.0.1\lib\net40\Renci.SshNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Security.AccessControl, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.AccessControl.5.0.0\lib\net461\System.Security.AccessControl.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Principal.Windows, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Text.Encoding.CodePages, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Text.Encoding.CodePages.6.0.0\lib\net461\System.Text.Encoding.CodePages.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encodings.Web, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Text.Encodings.Web.7.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Json, Version=7.0.0.3, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Text.Json.7.0.3\lib\net462\System.Text.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
@@ -111,6 +157,15 @@
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WebDriver, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Selenium.WebDriver.4.16.2\lib\netstandard2.0\WebDriver.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WebDriver.Support, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Selenium.Support.4.16.2\lib\netstandard2.0\WebDriver.Support.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WebDriverManager, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\WebDriverManager.2.17.1\lib\net462\WebDriverManager.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CExt.cs" />
|
||||
@@ -125,6 +180,14 @@
|
||||
<DependentUpon>Reference.svcmap</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="CUtill.cs" />
|
||||
<Compile Include="SearchModel\BookSearchService.cs" />
|
||||
<Compile Include="SearchModel\ChromeDriverManager.cs" />
|
||||
<Compile Include="SearchModel\DownloadProgressForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SearchModel\ILibrarySearcher.cs" />
|
||||
<Compile Include="SearchModel\KwangjuCityLibrarySearcher.cs" />
|
||||
<Compile Include="SearchModel\NamguLibrarySearcher.cs" />
|
||||
<Compile Include="마스터\From_User_manage_List.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -1868,4 +1931,11 @@
|
||||
<Content Include="Resources\3_2_2_편목.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\packages\Selenium.WebDriver.4.16.2\build\Selenium.WebDriver.targets" Condition="Exists('..\packages\Selenium.WebDriver.4.16.2\build\Selenium.WebDriver.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>이 프로젝트는 이 컴퓨터에 없는 NuGet 패키지를 참조합니다. 해당 패키지를 다운로드하려면 NuGet 패키지 복원을 사용하십시오. 자세한 내용은 http://go.microsoft.com/fwlink/?LinkID=322105를 참조하십시오. 누락된 파일은 {0}입니다.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Selenium.WebDriver.4.16.2\build\Selenium.WebDriver.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Selenium.WebDriver.4.16.2\build\Selenium.WebDriver.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -9,6 +9,7 @@
|
||||
<ErrorReportUrlHistory />
|
||||
<FallbackCulture>ko-KR</FallbackCulture>
|
||||
<VerifyUploadedFiles>false</VerifyUploadedFiles>
|
||||
<ProjectView>ProjectFiles</ProjectView>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<EnableSecurityDebugging>false</EnableSecurityDebugging>
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net472" />
|
||||
<package id="AngleSharp" version="1.0.4" targetFramework="net472" />
|
||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="7.0.0" targetFramework="net472" />
|
||||
<package id="Microsoft.Win32.Registry" version="5.0.0" targetFramework="net472" />
|
||||
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
|
||||
<package id="Selenium.Support" version="4.16.2" targetFramework="net472" />
|
||||
<package id="Selenium.WebDriver" version="4.16.2" targetFramework="net472" />
|
||||
<package id="SharpZipLib" version="1.4.2" targetFramework="net472" />
|
||||
<package id="SSH.NET" version="2020.0.1" targetFramework="net472" />
|
||||
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
|
||||
<package id="System.Memory" version="4.5.5" targetFramework="net472" />
|
||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" />
|
||||
<package id="System.Security.AccessControl" version="5.0.0" targetFramework="net472" />
|
||||
<package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net472" />
|
||||
<package id="System.Text.Encoding.CodePages" version="6.0.0" targetFramework="net472" />
|
||||
<package id="System.Text.Encodings.Web" version="7.0.0" targetFramework="net472" />
|
||||
<package id="System.Text.Json" version="7.0.3" targetFramework="net472" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
|
||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
|
||||
<package id="WebDriverManager" version="2.17.1" targetFramework="net472" />
|
||||
</packages>
|
||||
12
unimarc/unimarc/마크/Check_Copy_Sub_Search.Designer.cs
generated
12
unimarc/unimarc/마크/Check_Copy_Sub_Search.Designer.cs
generated
@@ -36,6 +36,7 @@ namespace UniMarc.마크
|
||||
this.lib_name = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.Code = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.URL = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.dvc_searcher = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
@@ -58,7 +59,8 @@ namespace UniMarc.마크
|
||||
this.Area,
|
||||
this.lib_name,
|
||||
this.Code,
|
||||
this.URL});
|
||||
this.URL,
|
||||
this.dvc_searcher});
|
||||
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
|
||||
this.dataGridView1.Name = "dataGridView1";
|
||||
@@ -105,6 +107,13 @@ namespace UniMarc.마크
|
||||
this.URL.ReadOnly = true;
|
||||
this.URL.Visible = false;
|
||||
//
|
||||
// dvc_searcher
|
||||
//
|
||||
this.dvc_searcher.HeaderText = "Searcher";
|
||||
this.dvc_searcher.Name = "dvc_searcher";
|
||||
this.dvc_searcher.ReadOnly = true;
|
||||
this.dvc_searcher.Visible = false;
|
||||
//
|
||||
// Check_Copy_Sub_Search
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
|
||||
@@ -126,5 +135,6 @@ namespace UniMarc.마크
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn lib_name;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn Code;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn URL;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dvc_searcher;
|
||||
}
|
||||
}
|
||||
@@ -26,15 +26,17 @@ namespace UniMarc.마크
|
||||
this.Text = string.Format("검색어 : [{0}]", SearchText);
|
||||
|
||||
// Province, Area, lib_name, Code
|
||||
string[] grid = { "", "", "", "", "" };
|
||||
string[] grid = { "", "", "", "", "", "" };
|
||||
for (int a = 0; a < ary.Length; a++)
|
||||
{
|
||||
if (a % 5 == 0) grid[0] = ary[a];
|
||||
if (a % 5 == 1) grid[1] = ary[a];
|
||||
if (a % 5 == 2) grid[2] = string.Format("{0}_{1}_{2}", grid[0], grid[1], ary[a]);
|
||||
if (a % 5 == 3) grid[3] = ary[a];
|
||||
if (a % 5 == 4) {
|
||||
grid[4] = ary[a];
|
||||
if (a % 6 == 0) grid[0] = ary[a];
|
||||
if (a % 6 == 1) grid[1] = ary[a];
|
||||
if (a % 6 == 2) grid[2] = string.Format("{0}_{1}_{2}", grid[0], grid[1], ary[a]);
|
||||
if (a % 6 == 3) grid[3] = ary[a];
|
||||
if (a % 6 == 4) grid[4] = ary[a];
|
||||
if (a % 6 == 5)
|
||||
{
|
||||
grid[5] = ary[a];
|
||||
dataGridView1.Rows.Add(grid);
|
||||
}
|
||||
}
|
||||
@@ -73,6 +75,7 @@ namespace UniMarc.마크
|
||||
string Code = dataGridView1.Rows[row].Cells["Code"].Value.ToString();
|
||||
string URL = dataGridView1.Rows[row].Cells["URL"].Value.ToString();
|
||||
string lib_name = dataGridView1.Rows[row].Cells["lib_name"].Value.ToString();
|
||||
string searcher = dataGridView1.Rows[row].Cells["dvc_searcher"].Value.ToString();
|
||||
|
||||
string lib_Category = string.Format("{0}_{1}", Province, Area);
|
||||
|
||||
@@ -80,6 +83,7 @@ namespace UniMarc.마크
|
||||
cc.Code = Code;
|
||||
cc.URL = URL;
|
||||
cc.tb_SearchTarget.Text = lib_name;
|
||||
cc.SearcherNo = searcher;
|
||||
|
||||
if (lib_name.Contains("Kolasys.net"))
|
||||
{
|
||||
|
||||
@@ -132,4 +132,7 @@
|
||||
<metadata name="URL.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dvc_searcher.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
66
unimarc/unimarc/마크/Check_copy.Designer.cs
generated
66
unimarc/unimarc/마크/Check_copy.Designer.cs
generated
@@ -28,7 +28,7 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.rb_isNumber = new System.Windows.Forms.RadioButton();
|
||||
this.rb_isHave = new System.Windows.Forms.RadioButton();
|
||||
@@ -39,7 +39,7 @@
|
||||
this.btn_Close = new System.Windows.Forms.Button();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.tb_SearchTarget = new System.Windows.Forms.TextBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.btSearchLibrary = new System.Windows.Forms.Button();
|
||||
this.panel2 = new System.Windows.Forms.Panel();
|
||||
this.btn_SiteDenote = new System.Windows.Forms.Button();
|
||||
this.lbl_PW = new System.Windows.Forms.Label();
|
||||
@@ -51,6 +51,8 @@
|
||||
this.btn_ApplyFilter = new System.Windows.Forms.Button();
|
||||
this.panel3 = new System.Windows.Forms.Panel();
|
||||
this.panel6 = new System.Windows.Forms.Panel();
|
||||
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
||||
this.lblStatus = new System.Windows.Forms.ToolStripLabel();
|
||||
this.panel4 = new System.Windows.Forms.Panel();
|
||||
this.chk_RemoveBrit = new System.Windows.Forms.CheckBox();
|
||||
this.btn_ResultEmpty = new System.Windows.Forms.Button();
|
||||
@@ -65,6 +67,7 @@
|
||||
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
|
||||
this.panel3.SuspendLayout();
|
||||
this.panel6.SuspendLayout();
|
||||
this.statusStrip1.SuspendLayout();
|
||||
this.panel4.SuspendLayout();
|
||||
this.panel5.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
@@ -176,14 +179,15 @@
|
||||
this.tb_SearchTarget.TabIndex = 1;
|
||||
this.tb_SearchTarget.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tb_SearchTarget_KeyDown);
|
||||
//
|
||||
// label1
|
||||
// btSearchLibrary
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(8, 10);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(53, 12);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "검색대상";
|
||||
this.btSearchLibrary.AutoSize = true;
|
||||
this.btSearchLibrary.Location = new System.Drawing.Point(3, 5);
|
||||
this.btSearchLibrary.Name = "btSearchLibrary";
|
||||
this.btSearchLibrary.Size = new System.Drawing.Size(63, 23);
|
||||
this.btSearchLibrary.TabIndex = 0;
|
||||
this.btSearchLibrary.Text = "검색대상";
|
||||
this.btSearchLibrary.Click += new System.EventHandler(this.btSearchLibrary_Click);
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
@@ -193,7 +197,7 @@
|
||||
this.panel2.Controls.Add(this.lbl_ID);
|
||||
this.panel2.Controls.Add(this.SearchCount);
|
||||
this.panel2.Controls.Add(this.tb_SearchTarget);
|
||||
this.panel2.Controls.Add(this.label1);
|
||||
this.panel2.Controls.Add(this.btSearchLibrary);
|
||||
this.panel2.Controls.Add(this.btn_Close);
|
||||
this.panel2.Controls.Add(this.label2);
|
||||
this.panel2.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
@@ -236,14 +240,14 @@
|
||||
this.dataGridView1.BackgroundColor = System.Drawing.SystemColors.Control;
|
||||
this.dataGridView1.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.dataGridView1.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
|
||||
dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
|
||||
dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Control;
|
||||
dataGridViewCellStyle2.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||
dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||
dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
|
||||
this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle2;
|
||||
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
|
||||
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control;
|
||||
dataGridViewCellStyle1.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
|
||||
this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
|
||||
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
|
||||
this.book_name,
|
||||
@@ -253,7 +257,7 @@
|
||||
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
|
||||
this.dataGridView1.Name = "dataGridView1";
|
||||
this.dataGridView1.RowTemplate.Height = 23;
|
||||
this.dataGridView1.Size = new System.Drawing.Size(629, 636);
|
||||
this.dataGridView1.Size = new System.Drawing.Size(629, 614);
|
||||
this.dataGridView1.TabIndex = 1;
|
||||
this.dataGridView1.RowPostPaint += new System.Windows.Forms.DataGridViewRowPostPaintEventHandler(this.dataGridView1_RowPostPaint);
|
||||
this.dataGridView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.dataGridView1_KeyDown);
|
||||
@@ -304,12 +308,29 @@
|
||||
// panel6
|
||||
//
|
||||
this.panel6.Controls.Add(this.dataGridView1);
|
||||
this.panel6.Controls.Add(this.statusStrip1);
|
||||
this.panel6.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel6.Location = new System.Drawing.Point(0, 102);
|
||||
this.panel6.Name = "panel6";
|
||||
this.panel6.Size = new System.Drawing.Size(629, 636);
|
||||
this.panel6.TabIndex = 3;
|
||||
//
|
||||
// statusStrip1
|
||||
//
|
||||
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.lblStatus});
|
||||
this.statusStrip1.Location = new System.Drawing.Point(0, 614);
|
||||
this.statusStrip1.Name = "statusStrip1";
|
||||
this.statusStrip1.Size = new System.Drawing.Size(629, 22);
|
||||
this.statusStrip1.TabIndex = 2;
|
||||
this.statusStrip1.Text = "statusStrip1";
|
||||
//
|
||||
// lblStatus
|
||||
//
|
||||
this.lblStatus.Name = "lblStatus";
|
||||
this.lblStatus.Size = new System.Drawing.Size(27, 20);
|
||||
this.lblStatus.Text = "WD";
|
||||
//
|
||||
// panel4
|
||||
//
|
||||
this.panel4.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
@@ -413,6 +434,9 @@
|
||||
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
|
||||
this.panel3.ResumeLayout(false);
|
||||
this.panel6.ResumeLayout(false);
|
||||
this.panel6.PerformLayout();
|
||||
this.statusStrip1.ResumeLayout(false);
|
||||
this.statusStrip1.PerformLayout();
|
||||
this.panel4.ResumeLayout(false);
|
||||
this.panel4.PerformLayout();
|
||||
this.panel5.ResumeLayout(false);
|
||||
@@ -423,7 +447,7 @@
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Button btSearchLibrary;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Panel panel2;
|
||||
private System.Windows.Forms.Button btn_Close;
|
||||
@@ -452,5 +476,7 @@
|
||||
public System.Windows.Forms.Label lbl_ID;
|
||||
private System.Windows.Forms.Button btn_SiteDenote;
|
||||
private System.Windows.Forms.WebBrowser webBrowser1;
|
||||
private System.Windows.Forms.StatusStrip statusStrip1;
|
||||
private System.Windows.Forms.ToolStripLabel lblStatus;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using System.Windows.Forms;
|
||||
using UniMarc.마크;
|
||||
using BokBonCheck;
|
||||
using AR;
|
||||
|
||||
namespace WindowsFormsApp1.Mac
|
||||
{
|
||||
@@ -15,6 +17,7 @@ namespace WindowsFormsApp1.Mac
|
||||
public string URL;
|
||||
public string lib_Category;
|
||||
public string Code;
|
||||
public string SearcherNo;
|
||||
private bool isStop = false;
|
||||
Main main;
|
||||
public Check_copy(Main _main)
|
||||
@@ -22,6 +25,20 @@ namespace WindowsFormsApp1.Mac
|
||||
InitializeComponent();
|
||||
main = _main;
|
||||
db.DBcon();
|
||||
|
||||
//도서검색(크롤링)
|
||||
_searchService = new BookSearchService();
|
||||
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_central());
|
||||
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_choisangjun());
|
||||
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_dagachi());
|
||||
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_Indi());
|
||||
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_Student());
|
||||
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_Kumho());
|
||||
_searchService.AddSearcher(new NamguLibrarySearcher_Munhwa(1));
|
||||
_searchService.AddSearcher(new NamguLibrarySearcher_Children(2));
|
||||
_searchService.AddSearcher(new NamguLibrarySearcher_Smart(3));
|
||||
_searchService.AddSearcher(new NamguLibrarySearcher_Purungil(4));
|
||||
_searchService.AddSearcher(new NamguLibrarySearcher_Hyocheon(5));
|
||||
}
|
||||
|
||||
private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
|
||||
@@ -30,14 +47,119 @@ namespace WindowsFormsApp1.Mac
|
||||
sg.Print_Grid_Num(sender, e);
|
||||
}
|
||||
|
||||
private void Check_copy_Load(object sender, EventArgs e)
|
||||
{
|
||||
string[] Grid = { "----- 빈칸으로 놔주세요 -----", "빈칸", "" };
|
||||
dataGridView1.Rows.Add(Grid);
|
||||
|
||||
this.Show();
|
||||
Application.DoEvents();
|
||||
|
||||
//크롤링
|
||||
InitializeChromeDriver();
|
||||
}
|
||||
|
||||
|
||||
#region 크롤링
|
||||
|
||||
private readonly BookSearchService _searchService;
|
||||
private bool _isSearching = false;
|
||||
private bool _isDriverReady = false;
|
||||
|
||||
private async void InitializeChromeDriver()
|
||||
{
|
||||
var lblStatus = this.lblStatus;// (Label)this.Controls["lblStatus"];
|
||||
lblStatus.Text = "WebDriver:Chrome 드라이버 확인 중...";
|
||||
lblStatus.ForeColor = Color.Blue;
|
||||
|
||||
try
|
||||
{
|
||||
// Chrome 설치 확인
|
||||
if (!ChromeDriverManager.IsChromeInstalled())
|
||||
{
|
||||
MessageBox.Show("Google Chrome이 설치되어 있지 않습니다. Chrome을 설치한 후 프로그램을 다시 실행해주세요.",
|
||||
"Chrome 필요", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
lblStatus.Text = "WebDriver:Chrome이 설치되지 않음";
|
||||
lblStatus.ForeColor = Color.Red;
|
||||
return;
|
||||
}
|
||||
|
||||
// 기존 드라이버가 준비되어 있는지 확인
|
||||
if (ChromeDriverManager.IsDriverReady())
|
||||
{
|
||||
lblStatus.Text = "WebDriver:Ready";
|
||||
lblStatus.ForeColor = Color.Green;
|
||||
_isDriverReady = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// 드라이버가 없거나 작동하지 않으면 다운로드 진행 창 표시
|
||||
using (var progressForm = new DownloadProgressForm())
|
||||
{
|
||||
progressForm.Show();
|
||||
|
||||
try
|
||||
{
|
||||
// ChromeDriver 설정
|
||||
await ChromeDriverManager.SetupChromeDriverAsync(progressForm);
|
||||
|
||||
// 드라이버 테스트
|
||||
var isWorking = await ChromeDriverManager.TestChromeDriverAsync(progressForm);
|
||||
|
||||
if (isWorking)
|
||||
{
|
||||
_isDriverReady = true;
|
||||
lblStatus.Text = "WebDriver:Ready";
|
||||
lblStatus.ForeColor = Color.Green;
|
||||
}
|
||||
else
|
||||
{
|
||||
lblStatus.Text = "WebDriver:Chrome 드라이버 테스트 실패";
|
||||
lblStatus.ForeColor = Color.Red;
|
||||
MessageBox.Show("Chrome 드라이버 테스트에 실패했습니다. 인터넷 연결을 확인하고 프로그램을 다시 실행해주세요.",
|
||||
"드라이버 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
lblStatus.Text = "WebDriver:드라이버 다운로드가 취소되었습니다.";
|
||||
lblStatus.ForeColor = Color.Orange;
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lblStatus.Text = "WebDriver:Chrome 드라이버 설정 실패";
|
||||
lblStatus.ForeColor = Color.Red;
|
||||
MessageBox.Show($"Chrome 드라이버 설정 중 오류가 발생했습니다: {ex.Message}",
|
||||
"설정 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lblStatus.Text = "WebDriver:Chrome 드라이버 설정 실패";
|
||||
lblStatus.ForeColor = Color.Red;
|
||||
MessageBox.Show($"Chrome 드라이버 설정 중 오류가 발생했습니다: {ex.Message}",
|
||||
"설정 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
private void tb_SearchTarget_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Enter)
|
||||
{
|
||||
SearchLibrary();
|
||||
}
|
||||
}
|
||||
void SearchLibrary()
|
||||
{
|
||||
string Target = tb_SearchTarget.Text;
|
||||
// if (Target == "") { MessageBox.Show("도서관명이 비어있습니다."); return; }
|
||||
|
||||
string area = "`Province`, `Area`, `LibName`, `Code`, `URL`";
|
||||
string area = "`Province`, `Area`, `LibName`, `Code`, `URL`, `SearcherNo`";
|
||||
string cmd = string.Format("SELECT {0} FROM `lib_CopyCheck` WHERE CONCAT( province , '_' , AREA , '_' , libname) LIKE '%{1}%';", area, Target);
|
||||
string data = db.self_Made_Cmd(cmd);
|
||||
string[] ary = data.Split('|');
|
||||
@@ -45,7 +167,6 @@ namespace WindowsFormsApp1.Mac
|
||||
ccs.Init(ary, Target);
|
||||
ccs.Show();
|
||||
}
|
||||
}
|
||||
|
||||
private void btn_SearchList_Click(object sender, EventArgs e)
|
||||
{
|
||||
@@ -61,17 +182,26 @@ namespace WindowsFormsApp1.Mac
|
||||
SearchCount.Value = dataGridView1.Rows.Count;
|
||||
}
|
||||
|
||||
private void btn_Start_Click(object sender, EventArgs e)
|
||||
async private void btn_Start_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (tb_SearchTarget.Text.Contains("Kolasys.net"))
|
||||
var libraryName = tb_SearchTarget.Text.Trim();
|
||||
if (libraryName.isEmpty())
|
||||
{
|
||||
tb_SearchTarget.Focus();
|
||||
UTIL.MsgE("도서관을 선택하세요");
|
||||
return;
|
||||
}
|
||||
if (libraryName.Contains("Kolasys.net"))
|
||||
{
|
||||
if (lbl_ID.Text == " " || lbl_PW.Text == " ")
|
||||
{
|
||||
MessageBox.Show("해당 도서관은 로그인정보가 필요합니다.\n복본조사 창을 껏다켜주세요.");
|
||||
UTIL.MsgE("해당 도서관은 로그인정보가 필요합니다.\n복본조사 창을 껏다켜주세요.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
isIksanClick = false;
|
||||
isJBEClick = false;
|
||||
isJNLClick = false;
|
||||
@@ -85,10 +215,13 @@ namespace WindowsFormsApp1.Mac
|
||||
|
||||
dataGridView1.CurrentCell = dataGridView1.Rows[0].Cells[0];
|
||||
|
||||
webBrowser1.Navigate("");
|
||||
|
||||
int SCount = Convert.ToInt32(SearchCount.Value);
|
||||
|
||||
if (SearcherNo.toInt() < 1)
|
||||
{
|
||||
//legacy
|
||||
webBrowser1.Visible = true;
|
||||
webBrowser1.Navigate("");
|
||||
if (URL is null)
|
||||
{
|
||||
webBrowser1.DocumentCompleted -= this.webBrowser1_DocumentCompleted;
|
||||
@@ -145,6 +278,105 @@ namespace WindowsFormsApp1.Mac
|
||||
webBrowser1.DocumentCompleted += this.webBrowser1_DocumentCompleted;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DateTime.Now > new DateTime(2025,08,31))
|
||||
{
|
||||
UTIL.MsgE("테스트 기간이 종료되었습니다\n개발자 문의 하세요");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._isDriverReady == false)
|
||||
{
|
||||
UTIL.MsgE("웹드라이버가 초기화되지 않았습니다\n1.크롬브라우즈가 설치되어있는지 확인하세요\n\n2.개발자 문의하세요");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//chrome web driver
|
||||
webBrowser1.Visible = false;
|
||||
var searcher = this._searchService.Get(this.SearcherNo.toInt());
|
||||
if (searcher == null)
|
||||
{
|
||||
UTIL.MsgE($"검색서비스가 존재하지 않습니다. 개발자에 문의 하세요\n검색서비스번호:{SearcherNo}");
|
||||
return;
|
||||
}
|
||||
|
||||
this._isSearching = true;
|
||||
btn_Start.Enabled = false;
|
||||
btn_Stop.Enabled = false;
|
||||
searcher.StartDriver();
|
||||
foreach (DataGridViewRow drow in this.dataGridView1.Rows)
|
||||
{
|
||||
if (this._isSearching == false)
|
||||
{
|
||||
drow.Cells["Count"].Value = "SKIP";
|
||||
continue;
|
||||
}
|
||||
|
||||
dataGridView1.CurrentCell = drow.Cells[0];
|
||||
//var vBookName = drow.Cells["book_name"].Value;
|
||||
var bookName = drow.Cells["book_name"].Value?.ToString() ?? string.Empty;
|
||||
if (bookName.isEmpty())
|
||||
{
|
||||
drow.DefaultCellStyle.BackColor = Color.HotPink;
|
||||
drow.DefaultCellStyle.ForeColor = Color.Blue;
|
||||
continue;
|
||||
}
|
||||
|
||||
var cntValue = drow.Cells["Count"].Value?.ToString() ?? string.Empty;
|
||||
if (cntValue.Equals("SKIP"))
|
||||
{
|
||||
drow.DefaultCellStyle.BackColor = Color.LightSkyBlue;
|
||||
drow.DefaultCellStyle.ForeColor = Color.Black;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
var rlt = await searcher.SearchAsync(bookName);
|
||||
if (rlt.IsSuccess)
|
||||
{
|
||||
drow.Cells["Count"].Value = $"{rlt.BookCount}";
|
||||
if (rlt.BookCount == 0)
|
||||
{
|
||||
drow.DefaultCellStyle.BackColor = Color.LightGray;
|
||||
drow.DefaultCellStyle.ForeColor = Color.Red;
|
||||
}
|
||||
else
|
||||
{
|
||||
drow.DefaultCellStyle.BackColor = Color.Yellow;
|
||||
drow.DefaultCellStyle.ForeColor = Color.Blue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
drow.DefaultCellStyle.BackColor = Color.HotPink;
|
||||
drow.DefaultCellStyle.ForeColor = Color.Blue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
searcher.StopDriver();
|
||||
UTIL.MsgI("검색 완료");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UTIL.MsgE("Web Driver Error\n"+ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
btn_Stop.Enabled = true;
|
||||
btn_Start.Enabled = true;
|
||||
this._isSearching = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int RowCount = 0;
|
||||
@@ -1348,6 +1580,7 @@ namespace WindowsFormsApp1.Mac
|
||||
|
||||
private void btn_Stop_Click(object sender, EventArgs e)
|
||||
{
|
||||
_isSearching = false;
|
||||
webBrowser1.Stop();
|
||||
webBrowser1.DocumentCompleted -= this.webBrowser1_DocumentCompleted;
|
||||
}
|
||||
@@ -1592,11 +1825,6 @@ namespace WindowsFormsApp1.Mac
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void Check_copy_Load(object sender, EventArgs e)
|
||||
{
|
||||
string[] Grid = { "----- 빈칸으로 놔주세요 -----", "빈칸", "" };
|
||||
dataGridView1.Rows.Add(Grid);
|
||||
}
|
||||
|
||||
private void Check_copy_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
@@ -1607,15 +1835,12 @@ namespace WindowsFormsApp1.Mac
|
||||
private void btn_SiteDenote_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (URL == null) return;
|
||||
try
|
||||
{
|
||||
System.Diagnostics.Process.Start(URL);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
AR.UTIL.RunExplorer(URL);
|
||||
}
|
||||
|
||||
private void btSearchLibrary_Click(object sender, EventArgs e)
|
||||
{
|
||||
SearchLibrary();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,4 +126,7 @@
|
||||
<metadata name="Count.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
Reference in New Issue
Block a user