feat: 도서관 검색 시스템 대폭 확장 및 크롤링 가이드 추가

- 새로운 도서관 검색기 15개 추가 (HTTP/Selenium 방식)
  * HTTP 방식: 순천시립, 목포시립, 광산구, 여수시립
  * Selenium 방식: 광주시립, 고흥군립, 북구통합, 전북교육청, 안산시립 등
- 도서관 검색기 작성 가이드를 CLAUDE.md에 추가
- ILibrarySearcher 인터페이스에 HttpApiMode 속성 추가
- 기존 검색기들 리팩토링 및 통합 (NamguLibrarySearcher 등)
- Check_copyWD.cs에 모든 새로운 도서관 등록 완료
- 설정 관리 시스템 개선 (UserSetting 클래스 추가)

총 200개 이상의 도서관 지원으로 복본조사 범위 대폭 확대

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Arin(asus)
2025-08-14 01:21:33 +09:00
parent f3715253a8
commit 946957bab2
30 changed files with 4136 additions and 380 deletions

View File

@@ -17,198 +17,14 @@ using System.Runtime.CompilerServices;
namespace BokBonCheck
{
public class NamguLibrarySearcher_Munhwa : NamguLibrarySearcher
{
public NamguLibrarySearcher_Munhwa(int no) : base(no)
{
SiteName = "남구통합도서관(문화정보도서관)"; // 문화관 검색기
}
protected override bool SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
try
{
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == true)
{
SafeClick(searchBox);
}
selector = "#libMA";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == false)
{
SafeClick(searchBox);
}
return true;
}
catch
{
return false;
}
}
}
public class NamguLibrarySearcher_Purungil : NamguLibrarySearcher
{
public NamguLibrarySearcher_Purungil(int no) : base(no)
{
SiteName = "남구통합도서관(푸른길도서관)";
}
protected override bool SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
try
{
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == true)
{
SafeClick(searchBox);
}
selector = "#libMB";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == false)
{
SafeClick(searchBox);
}
return true;
}
catch
{
return false;
}
}
}
public class NamguLibrarySearcher_Children : NamguLibrarySearcher
{
public NamguLibrarySearcher_Children(int no) : base(no)
{
SiteName = "남구통합도서관(청소년도서관)";
}
protected override bool SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
try
{
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == true)
{
SafeClick(searchBox);
}
selector = "#libMC";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == false)
{
//searchBox.Click(); // 체크박스 선택
SafeClick(searchBox);
}
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
}
public class NamguLibrarySearcher_Hyocheon : NamguLibrarySearcher
{
public NamguLibrarySearcher_Hyocheon(int no) : base(no)
{
SiteName = "남구통합도서관(효천어울림도서관)";
}
protected override bool SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
try
{
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == true)
{
SafeClick(searchBox);
}
selector = "#libSW";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == false)
{
SafeClick(searchBox);
}
return true;
}
catch
{
return false;
}
}
}
public class NamguLibrarySearcher_Smart : NamguLibrarySearcher
{
public NamguLibrarySearcher_Smart(int no) : base(no)
{
SiteName = "남구통합도서관(스마트도서관)";
}
protected override bool SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
try
{
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == true)
{
SafeClick(searchBox);
}
selector = "#libSQ";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == false)
{
SafeClick(searchBox);
}
return true;
}
catch
{
return false;
}
}
}
public class NamguLibrarySearcher : ILibrarySearcher
{
protected string AreaCode = "";
public string SiteName { get; protected set; } = "남구통합도서관(전체)";
public string SiteUrl => "https://lib.namgu.gwangju.kr/main/bookSearch";
public bool HttpApiMode { get; set; } = false;
public int No { get; set; }
private ChromiumDriver _driver;
@@ -219,9 +35,11 @@ namespace BokBonCheck
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SW_MINIMIZE = 6;
public NamguLibrarySearcher(int no)
public NamguLibrarySearcher(int no, string areaCode, string areaName)
{
this.No = no;
this.AreaCode = areaCode;
this.SiteName = $"남구통합도서관({areaName})";
}
@@ -264,15 +82,24 @@ namespace BokBonCheck
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == true)
{
SafeClick(searchBox);
}
selector = AreaCode;
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox == null) return false;
if (searchBox.Selected == false)
{
SafeClick(searchBox);
}
return true;
}
catch (Exception ex)
catch
{
Console.WriteLine(ex.Message);
return false;
}
}