dongnelibrary 0.3.17 → 0.3.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/.claude/settings.json +30 -1
  2. package/.claude/settings.local.json +26 -1
  3. package/.playwright-cli/console-2026-05-15T13-42-50-460Z.log +1 -0
  4. package/.playwright-cli/console-2026-05-15T13-43-40-832Z.log +10 -0
  5. package/.playwright-cli/console-2026-05-18T12-47-04-141Z.log +14 -0
  6. package/.playwright-cli/page-2026-05-07T11-53-37-538Z.yml +836 -0
  7. package/.playwright-cli/page-2026-05-07T11-54-02-314Z.yml +658 -0
  8. package/.playwright-cli/page-2026-05-07T12-03-12-317Z.yml +310 -0
  9. package/.playwright-cli/page-2026-05-08T13-54-43-061Z.yml +276 -0
  10. package/.playwright-cli/page-2026-05-08T13-54-45-094Z.yml +276 -0
  11. package/.playwright-cli/page-2026-05-08T13-54-53-014Z.yml +201 -0
  12. package/.playwright-cli/page-2026-05-08T13-56-02-097Z.yml +726 -0
  13. package/.playwright-cli/page-2026-05-08T13-56-33-697Z.yml +226 -0
  14. package/.playwright-cli/page-2026-05-15T13-42-51-601Z.yml +47 -0
  15. package/.playwright-cli/page-2026-05-15T13-43-40-955Z.yml +47 -0
  16. package/.playwright-cli/page-2026-05-15T13-43-43-563Z.yml +47 -0
  17. package/.playwright-cli/page-2026-05-18T12-47-05-318Z.yml +135 -0
  18. package/README.md +59 -2
  19. package/dist/dongnelibrary.d.ts.map +1 -1
  20. package/dist/dongnelibrary.js +36 -0
  21. package/dist/dongnelibrary.js.map +1 -1
  22. package/dist/localLibraryModule/ansan.d.ts +6 -0
  23. package/dist/localLibraryModule/ansan.d.ts.map +1 -0
  24. package/dist/localLibraryModule/ansan.js +76 -0
  25. package/dist/localLibraryModule/ansan.js.map +1 -0
  26. package/dist/localLibraryModule/bcl.d.ts +6 -0
  27. package/dist/localLibraryModule/bcl.d.ts.map +1 -0
  28. package/dist/localLibraryModule/bcl.js +75 -0
  29. package/dist/localLibraryModule/bcl.js.map +1 -0
  30. package/dist/localLibraryModule/gangnam.d.ts +6 -0
  31. package/dist/localLibraryModule/gangnam.d.ts.map +1 -0
  32. package/dist/localLibraryModule/gangnam.js +100 -0
  33. package/dist/localLibraryModule/gangnam.js.map +1 -0
  34. package/dist/localLibraryModule/gangseo.d.ts +6 -0
  35. package/dist/localLibraryModule/gangseo.d.ts.map +1 -0
  36. package/dist/localLibraryModule/gangseo.js +90 -0
  37. package/dist/localLibraryModule/gangseo.js.map +1 -0
  38. package/dist/localLibraryModule/gbelib.d.ts +6 -0
  39. package/dist/localLibraryModule/gbelib.d.ts.map +1 -0
  40. package/dist/localLibraryModule/gbelib.js +122 -0
  41. package/dist/localLibraryModule/gbelib.js.map +1 -0
  42. package/dist/localLibraryModule/geoje.d.ts +6 -0
  43. package/dist/localLibraryModule/geoje.d.ts.map +1 -0
  44. package/dist/localLibraryModule/geoje.js +75 -0
  45. package/dist/localLibraryModule/geoje.js.map +1 -0
  46. package/dist/localLibraryModule/gimhae.d.ts +6 -0
  47. package/dist/localLibraryModule/gimhae.d.ts.map +1 -0
  48. package/dist/localLibraryModule/gimhae.js +81 -0
  49. package/dist/localLibraryModule/gimhae.js.map +1 -0
  50. package/dist/localLibraryModule/gunsan.d.ts +6 -0
  51. package/dist/localLibraryModule/gunsan.d.ts.map +1 -0
  52. package/dist/localLibraryModule/gunsan.js +89 -0
  53. package/dist/localLibraryModule/gunsan.js.map +1 -0
  54. package/dist/localLibraryModule/gwanak.d.ts +6 -0
  55. package/dist/localLibraryModule/gwanak.d.ts.map +1 -0
  56. package/dist/localLibraryModule/gwanak.js +103 -0
  57. package/dist/localLibraryModule/gwanak.js.map +1 -0
  58. package/dist/localLibraryModule/gwe.d.ts +6 -0
  59. package/dist/localLibraryModule/gwe.d.ts.map +1 -0
  60. package/dist/localLibraryModule/gwe.js +84 -0
  61. package/dist/localLibraryModule/gwe.js.map +1 -0
  62. package/dist/localLibraryModule/junggulib.d.ts +6 -0
  63. package/dist/localLibraryModule/junggulib.d.ts.map +1 -0
  64. package/dist/localLibraryModule/junggulib.js +96 -0
  65. package/dist/localLibraryModule/junggulib.js.map +1 -0
  66. package/dist/localLibraryModule/mokpolib.d.ts +6 -0
  67. package/dist/localLibraryModule/mokpolib.d.ts.map +1 -0
  68. package/dist/localLibraryModule/mokpolib.js +104 -0
  69. package/dist/localLibraryModule/mokpolib.js.map +1 -0
  70. package/dist/localLibraryModule/nowon.d.ts +6 -0
  71. package/dist/localLibraryModule/nowon.d.ts.map +1 -0
  72. package/dist/localLibraryModule/nowon.js +95 -0
  73. package/dist/localLibraryModule/nowon.js.map +1 -0
  74. package/dist/localLibraryModule/paju.d.ts +6 -0
  75. package/dist/localLibraryModule/paju.d.ts.map +1 -0
  76. package/dist/localLibraryModule/paju.js +94 -0
  77. package/dist/localLibraryModule/paju.js.map +1 -0
  78. package/dist/localLibraryModule/pohang.d.ts +6 -0
  79. package/dist/localLibraryModule/pohang.d.ts.map +1 -0
  80. package/dist/localLibraryModule/pohang.js +83 -0
  81. package/dist/localLibraryModule/pohang.js.map +1 -0
  82. package/dist/localLibraryModule/siheung.d.ts +6 -0
  83. package/dist/localLibraryModule/siheung.d.ts.map +1 -0
  84. package/dist/localLibraryModule/siheung.js +65 -0
  85. package/dist/localLibraryModule/siheung.js.map +1 -0
  86. package/dist/localLibraryModule/yangcheon.d.ts +6 -0
  87. package/dist/localLibraryModule/yangcheon.d.ts.map +1 -0
  88. package/dist/localLibraryModule/yangcheon.js +90 -0
  89. package/dist/localLibraryModule/yangcheon.js.map +1 -0
  90. package/dist/localLibraryModule/ydplib.d.ts +6 -0
  91. package/dist/localLibraryModule/ydplib.d.ts.map +1 -0
  92. package/dist/localLibraryModule/ydplib.js +101 -0
  93. package/dist/localLibraryModule/ydplib.js.map +1 -0
  94. package/docs/library-module-python-scripts.md +381 -0
  95. package/docs//355/206/265/355/225/251/353/217/204/354/204/234/302/240/353/204/244/355/212/270/354/233/214/355/201/254-/353/252/251/353/241/235.md +184 -0
  96. package/docs//355/206/265/355/225/251/353/217/204/354/204/234/352/264/200-/353/204/244/355/212/270/354/233/214/355/201/254-/353/252/251/353/241/235.md +19 -19
  97. package/package.json +44 -6
  98. package/scripts/analyze-html-library.sh +300 -0
  99. package/scripts/analyze-library.sh +261 -0
@@ -0,0 +1,381 @@
1
+ # 도서관 모듈 추가 시 사용하는 Python/Bash 스크립트
2
+
3
+ > 새 도서관 모듈을 추가할 때 반복적으로 사용되는 분석 스크립트 모음입니다.
4
+ > 대부분의 기능은 `scripts/analyze-library.sh`에 통합되어 있습니다.
5
+
6
+ ---
7
+
8
+ ## 1. 도서관 분기(branch) 코드 수집
9
+
10
+ 검색 결과 응답에서 branch 정보를 자동 수집합니다.
11
+
12
+ ### 사용 시나리오
13
+ - pyxis 플랫폼처럼 도서관 목록 전용 API가 있을 경우: `bash scripts/analyze-library.sh libraries {API_URL}`
14
+ - 검색 결과에서 branch를 수집해야 하는 경우: 아래 인라인 스크립트 사용
15
+
16
+ ### 인라인 버전 (pyxis 계열 — 검색 결과에서 수집)
17
+
18
+ ```bash
19
+ curl -s "{SEARCH_URL}?all=k|a|도서관&max=200" | python3 -c "
20
+ import json, sys
21
+ data = json.load(sys.stdin)
22
+ books = data.get('data', {}).get('list', [])
23
+ branches = {}
24
+ for b in books:
25
+ for bv in b.get('branchVolumes', []):
26
+ bid = bv.get('id')
27
+ bname = bv.get('name')
28
+ if bid and bname:
29
+ branches[bid] = bname
30
+ for bid, bname in sorted(branches.items()):
31
+ print(f'{bid}: {bname}')
32
+ print('Total branches:', len(branches))
33
+ "
34
+ ```
35
+
36
+ ### pyxis 전용 branches API (lib.siheung.go.kr 에서 확인)
37
+
38
+ ```bash
39
+ curl -s "{BASE_URL}/pyxis-api/1/branches" | python3 -m json.tool
40
+ ```
41
+
42
+ pyxis 플랫폼은 `/pyxis-api/1/branches` 엔드포인트에서 전체 분관 목록을 JSON으로 반환합니다.
43
+ (gunpo, siheung 등 `ikc-pyxis-wrap` 클래스를 사용하는 AngularJS 기반 사이트에서 확인됨)
44
+
45
+ ---
46
+
47
+ ## 2. 검색 응답 구조 파악
48
+
49
+ ### 책·도서관 정보 추출 (pyxis 계열)
50
+
51
+ ```bash
52
+ curl -s "{SEARCH_URL}?all=k|a|별&max=3" | python3 -c "
53
+ import json, sys
54
+ data = json.load(sys.stdin)
55
+ books = data.get('data', {}).get('list', [])
56
+ for b in books[:2]:
57
+ print('title:', b.get('titleStatement'))
58
+ print('id:', b.get('id'))
59
+ print('branches:', b.get('branchVolumes'))
60
+ print()
61
+ "
62
+ ```
63
+
64
+ ### 총 건수 + 책 목록 확인 (범용)
65
+
66
+ ```bash
67
+ curl -s "{SEARCH_URL}?{PARAMS}" | python3 -c "
68
+ import json, sys
69
+ data = json.load(sys.stdin)
70
+ d = data.get('data', {})
71
+ print('totalCount:', d.get('totalCount'))
72
+ books = d.get('list', [])
73
+ for b in books[:2]:
74
+ print('title:', b.get('titleStatement'))
75
+ print('branches:', [(bv['name'], bv['cState']) for bv in b.get('branchVolumes', [])])
76
+ "
77
+ ```
78
+
79
+ ---
80
+
81
+ ## 3. 최대 조회 건수(max) 결정
82
+
83
+ 서버 성능에 맞는 안전한 max 값을 찾습니다.
84
+
85
+ ```bash
86
+ for max in 50 100 150 200 250 300 500 1000; do
87
+ result=$(curl -s -o /dev/null -w "%{http_code} %{time_total}s" \
88
+ "{SEARCH_URL}?all=k|a|별&branch={FIRST_BRANCH_CODE}&max=$max")
89
+ echo "max=$max: $result"
90
+ done
91
+ ```
92
+
93
+ **기준**: 단일 요청이 4초 이내여야 테스트 타임아웃 안에 완료됩니다.
94
+ ECONNRESET은 서버 하드 리밋 신호 — 직전 성공값의 85~90%를 안전값으로 설정합니다.
95
+
96
+ ---
97
+
98
+ ## 4. SSL 인증서 체인 확인
99
+
100
+ ```bash
101
+ openssl s_client -connect {HOSTNAME}:443 -servername {HOSTNAME} 2>&1 | head -20
102
+ ```
103
+
104
+ `unable to get local issuer certificate` 오류가 보이면 중간 CA 누락 — 모듈에서
105
+ `undici`의 `Agent({ connect: { rejectUnauthorized: false } })`를 사용해야 합니다.
106
+
107
+ ---
108
+
109
+ ## 5. 다양한 API 엔드포인트 탐색 (pyxis 계열)
110
+
111
+ ```bash
112
+ for endpoint in "1/branches" "1/libraries" "settings/branches" "common/branches" "1/collections/1/branches"; do
113
+ result=$(curl -s "https://{HOST}/pyxis-api/$endpoint" 2>/dev/null \
114
+ | python3 -c "import json,sys; d=json.load(sys.stdin); print('OK' if d.get('success') else 'FAIL: '+d.get('message','?'))" 2>/dev/null)
115
+ echo "$endpoint: $result"
116
+ done
117
+ ```
118
+
119
+ ---
120
+
121
+ ## 7. wkcms/KCMS 플랫폼 세션 기반 검색
122
+
123
+ 거제시도서관(`geoje`) 추가 시 발견된 wkcms 플랫폼 패턴입니다.
124
+ **특징**: Java Spring MVC 기반, 포트 9080, 검색 전 JSESSIONID 쿠키 필수.
125
+
126
+ ### JSESSIONID 쿠키 획득 → 검색 (curl 2단계)
127
+
128
+ ```bash
129
+ WKCMS="https://lib.geoje.go.kr:9080/wkcms"
130
+ # 1단계: 검색 페이지 방문 → 세션 쿠키 저장
131
+ curl -sk -c /tmp/wkcms.txt "$WKCMS/KBookSearch/BookSearchPage/MA" -o /dev/null
132
+
133
+ # 2단계: 쿠키로 검색 (manage_code = 도서관 코드)
134
+ curl -sk -b /tmp/wkcms.txt \
135
+ "$WKCMS/KBookSearch/BookNomalSearch/MA?search_txt=별&book_type=BOOK&pageno=1&display=20&detail_search_type=Nomal&manage_code=MA&option=nomal&libcode=ALL&input_search_text=별&real_search_text=별&now_search_txt=별&hidden_book_type=BOOK&orderby=ASC&orderby_item=TITLE_INFO_SORT" \
136
+ | python3 -c "
137
+ import sys, re
138
+ html = sys.stdin.read()
139
+ total = re.search(r'총\s*([\d,]+)\s*건', html)
140
+ print('총 건수:', total.group(1) if total else '없음')
141
+ print('응답 크기:', len(html), 'bytes')
142
+ available = html.count('loan_o')
143
+ print('대출가능 td.loan_o 개수:', available)
144
+ titles = re.findall(r'<h4[^>]*>\s*(.*?)\s*</h4>', html, re.DOTALL)[:3]
145
+ for t in titles: print(' -', re.sub(r'<[^>]+>', '', t).strip()[:80])
146
+ "
147
+ ```
148
+
149
+ ### HTML에서 도서관 코드 추출 (wkcms 체크박스)
150
+
151
+ ```bash
152
+ curl -sk -c /tmp/wkcms.txt "https://HOST:9080/wkcms/KBookSearch/BookSearchPage/MA" | python3 -c "
153
+ import sys, re
154
+ html = sys.stdin.read()
155
+ # 체크박스 name='manage_code' value='MA' 패턴
156
+ codes = re.findall(r\"name=['\\\"]manage_code['\\\"][^>]+value=['\\\"]([A-Z]+)['\\\"]\", html)
157
+ if not codes:
158
+ # 속성 순서 다를 때
159
+ inputs = re.findall(r'<input[^>]+>', html, re.I)
160
+ codes = [re.search(r'value=[\"']([A-Z]+)[\"']', i).group(1)
161
+ for i in inputs if 'manage_code' in i.lower()
162
+ if re.search(r'value=[\"']([A-Z]+)[\"']', i)]
163
+ unique = list(dict.fromkeys(codes))
164
+ print(f'{len(unique)}개 코드:')
165
+ for c in unique: print(' ', c)
166
+ "
167
+ ```
168
+
169
+ ### 성능 테스트 (display 값 탐색, 세션 필요)
170
+
171
+ wkcms는 `display` 파라미터로 한 번에 가져올 최대 건수를 조정합니다.
172
+ 세션 쿠키 없이는 오류 페이지가 반환되므로 반드시 2단계 방식으로 테스트합니다.
173
+
174
+ ```bash
175
+ INIT_URL="https://HOST:9080/wkcms/KBookSearch/BookSearchPage/MA"
176
+ for display in 10 20 50 100 200; do
177
+ curl -sk -c /tmp/wkcms.txt "$INIT_URL" -o /dev/null
178
+ printf "display=%-6s " "$display:"
179
+ curl -sk -b /tmp/wkcms.txt -o /dev/null -w "HTTP %{http_code} - %{time_total}s\n" \
180
+ "https://HOST:9080/wkcms/KBookSearch/BookNomalSearch/MA?search_txt=별&book_type=BOOK&pageno=1&display=$display&detail_search_type=Nomal&manage_code=MA&option=nomal&libcode=ALL&input_search_text=별&real_search_text=별&now_search_txt=별&hidden_book_type=BOOK&orderby=ASC&orderby_item=TITLE_INFO_SORT"
181
+ done
182
+ ```
183
+
184
+ 범용 버전은 `bash scripts/analyze-html-library.sh perf-test`를 사용합니다.
185
+
186
+ ---
187
+
188
+ ## 8. HTML 기반 사이트 폼/구조 분석 (`scripts/analyze-html-library.sh`)
189
+
190
+ SPA가 아닌 SSR HTML 도서관 사이트(wkcms, kolaseek, jnet 등) 분석용 스크립트.
191
+ 세션 쿠키 획득 + HTML 폼 구조 파악에 특화되어 있습니다.
192
+
193
+ ```bash
194
+ # wkcms 도서관 코드 자동 수집
195
+ bash scripts/analyze-html-library.sh wkcms-codes "lib.geoje.go.kr"
196
+
197
+ # 세션 초기화 후 검색 결과 요약
198
+ bash scripts/analyze-html-library.sh session-search \
199
+ "https://lib.geoje.go.kr:9080/wkcms/KBookSearch/BookSearchPage/MA" \
200
+ "https://lib.geoje.go.kr:9080/wkcms/KBookSearch/BookNomalSearch/MA?search_txt=별&..."
201
+
202
+ # HTML 폼의 action, hidden 파라미터, 체크박스 name 목록
203
+ bash scripts/analyze-html-library.sh form-info "https://example.library.go.kr/search.do"
204
+
205
+ # 도서관 코드 체크박스 name 자동 탐지
206
+ bash scripts/analyze-html-library.sh list-codes "https://example.go.kr/search.do" searchLibraryArr
207
+
208
+ # HTML 내 특정 패턴 주변 컨텍스트 출력
209
+ bash scripts/analyze-html-library.sh html-context "https://HOST:9080/wkcms/..." "ul.book_info"
210
+
211
+ # display 값별 응답 시간 측정 (세션 필요)
212
+ bash scripts/analyze-html-library.sh perf-test \
213
+ "https://HOST:9080/wkcms/KBookSearch/BookSearchPage/MA" \
214
+ "https://HOST:9080/wkcms/KBookSearch/BookNomalSearch/MA?search_txt=별&display=__DISPLAY__&..." \
215
+ 10 20 50 100 200
216
+
217
+ # SSL 인증서 확인 (포트 지정 가능)
218
+ bash scripts/analyze-html-library.sh ssl-check "lib.geoje.go.kr:9080"
219
+ ```
220
+
221
+ ---
222
+
223
+ ## 6. SPA 사이트 분석 (`scripts/analyze-library.sh` 통합 명령)
224
+
225
+ > **자세한 내용**: `/add-library-module` 스킬의 "SPA 분석 스크립트" 섹션 참조
226
+
227
+ ```bash
228
+ # JS 번들에서 API 엔드포인트 추출
229
+ bash scripts/analyze-library.sh endpoints "https://example.go.kr/app.abc123.js"
230
+
231
+ # 특정 패턴 주변 컨텍스트 확인 (API 파라미터 파악용)
232
+ bash scripts/analyze-library.sh context "https://example.go.kr/app.js" "/api/search"
233
+
234
+ # 도서관 목록 JSON API 파싱
235
+ bash scripts/analyze-library.sh libraries "https://example.go.kr/api/common/libraryInfo"
236
+
237
+ # POST 파라미터 유효값 탐색
238
+ bash scripts/analyze-library.sh test-param "https://example.go.kr/api/search" \
239
+ '{"searchKeyword":"별","manageCode":"AA","page":"1","display":"3"}' \
240
+ article TITLE AUTHOR LOANABLE ALL SCORE
241
+ ```
242
+
243
+ ---
244
+
245
+ ## 플랫폼별 분기 코드 형식 요약
246
+
247
+ | 플랫폼 | 분기 파라미터 | 코드 형식 | 예시 |
248
+ |--------|-------------|---------|------|
249
+ | pyxis (gunpo, siheung) | `branch` | 숫자 ID | `1`, `81` |
250
+ | alpasq (bcl, nowon) | `manageCode` | 2자리 알파벳 | `"AA"`, `["AG"]` |
251
+ | jnet/galib (gwanak, gangnam) | `searchLibraryArr` | 2자리 알파벳 | `MA` |
252
+ | dls_le (asan, cbelib) | `manageCode` | 2자리 알파벳 | `MF` |
253
+ | wkcms/KCMS (geoje) | `manage_code` | 2자리 알파벳 | `MA`, `MC` |
254
+ | nanum (yangcheon) | `manage_code` | 2자리 알파벳 | `MA`, `MH` |
255
+ | suwon | `libraryCode` | 6자리 숫자 | `111000` |
256
+
257
+ ---
258
+
259
+ ## 거제시도서관 추가에서 확인된 사항 (wkcms 플랫폼)
260
+
261
+ - **wkcms 플랫폼 감지**: URL에 `:9080/wkcms/` 경로 또는 `BookSearchPage`/`BookNomalSearch` 패턴이 있으면 wkcms 계열
262
+ - **JSESSIONID 필수**: 쿠키 없이 검색하면 "오류가 발생했습니다" 에러 페이지 반환. 반드시 `createSession()`으로 세션 초기화 후 검색
263
+ - **필수 파라미터 세트**: `search_txt`, `input_search_text`, `real_search_text`, `now_search_txt` 4개가 모두 동일한 키워드여야 함 — 하나라도 누락되면 오류
264
+ - **URLSearchParams 사용**: `http.ts`의 `session.get()`은 `qs` 옵션 미지원 → `new URLSearchParams({...}).toString()`으로 쿼리 스트링 직접 빌드
265
+ - **대출 상태**: `td.loan_o` CSS 클래스 존재 여부로 판단 (`loan_o` = 대출가능)
266
+ - **도서 제목**: `ul.book_info > li h4` textContent
267
+ - **bookUrl 없음**: wkcms는 개별 도서 상세 페이지가 없음 → `bookPrintPopup` URL을 대안으로 사용, `SESSION_REQUIRED_DOMAINS`에 도메인 추가하여 테스트 스킵
268
+ - **MB 코드 이상**: 거제시립옥포도서관(MB)은 단독 검색 시 항상 0건 반환 → 제외
269
+ - **display=20 안전**: 더 높이면 응답 시간 급증 (100=7초). 20이 1.5초로 안전
270
+ - **englishSearchTerm 필요**: MA 도서관은 "javascript" 검색 결과 0건 → `{ englishSearchTerm: "java" }` 지정
271
+
272
+ ## 경상북도교육청통합도서관(gbelib) 추가에서 확인된 사항
273
+
274
+ - **플랫폼**: Spring MVC + Thymeleaf 기반 SSR 사이트. `gbelib.kr` → `www.gbelib.kr/gbelib/` 리다이렉트
275
+ - **통합 검색 엔드포인트**: `GET /gbelib/intro/totalSearch/index.do?menu_idx=150&search_text={title}&search_type=L_TITLE&total_search_type=TOTAL&search_detail_yn=N&book_more_count=1&libraryCodes={code}`
276
+ - **총 건수 추출**: `id="bookTotalCnt"` 요소의 textContent (예: `9057`)
277
+ - **초기 3건 반환**: `book_more_count=1`이면 항상 3건만 `div.row` 형태로 반환
278
+ - **추가 건수 로드**: `GET /gbelib/intro/totalSearch/more.do?more_type=BOOK&...&book_more_count=N` — N=2부터 순서대로 3건씩 반환. 병렬 호출 가능 (~0.4초)
279
+ - **도서관 코드 형식**: 8자리 숫자 (`00147046`, `00347034` 등). HTML 체크박스의 `value` 속성에서 추출
280
+ - **책 항목 구조**: `div.row > div.box > div.item > div.bif` 안에:
281
+ - `a.name.goDetail` — 책 제목 (textContent에 `<span>` 하이라이트 포함, `textContent`로 추출)
282
+ - `vLoca` 속성 — 8자리 라이브러리 코드
283
+ - `vCtrl` 속성 — 도서 관리번호
284
+ - 두 번째 `<p>` — 도서관명
285
+ - **책 상세 URL**: `https://www.gbelib.kr/gbelib/intro/search/detail.do?vLoca={vLoca}&vCtrl={vCtrl}&menu_idx=150` — GET 요청으로 직접 접근 가능, 책 제목이 HTML에 포함됨
286
+ - **대출 상태**: `more.do` HTML 조각에 대출 상태 없음. `index_detail.do?vLoca={vLoca}&vCtrl={vCtrl}`로 별도 조회 가능하지만 책마다 추가 HTTP 요청이 필요해 실용적이지 않음 → `exist: false`로 설정
287
+ - **더 빠른 개별 도서관 검색**: 각 도서관은 별도 서브사이트 (`/gm/`, `/ad/` 등)를 가지며, `/{prefix}/intro/search/index.do?search_text={title}&rowCount=50`으로 최대 50건 반환. 하지만 전체 네트워크 코드와 매핑이 필요해 통합 검색 사용
288
+ - **병렬 more.do 호출로 30건**: 초기 1건 + more.do 9건 병렬 = 총 30건, 약 2-3초 소요
289
+
290
+ ### gbelib 분관 코드 수집 스크립트
291
+
292
+ ```python
293
+ import re
294
+
295
+ html = open('/tmp/gbelib_search.html').read()
296
+ libs = re.findall(
297
+ r'<input[^>]+name="libraryCodes"[^>]+value="([^"]+)"[^>]*/><label for="[^"]+">([^<]+)</label>',
298
+ html
299
+ )
300
+ for code, name in libs:
301
+ if code != 'ALL':
302
+ print(f' {{ code: "{code}", name: "{name}" }},')
303
+ ```
304
+
305
+ 또는 bash:
306
+ ```bash
307
+ curl -s "https://www.gbelib.kr/gbelib/intro/totalSearch/index.do?menu_idx=150" | python3 -c "
308
+ import sys, re
309
+ html = sys.stdin.read()
310
+ libs = re.findall(r'name=\"libraryCodes\"[^>]+value=\"([^\"]+)\"[^/]*/><label[^>]+>([^<]+)', html)
311
+ for code, name in libs:
312
+ if code != 'ALL':
313
+ print(f' {{ code: \"{code}\", name: \"{name}\" }},')
314
+ "
315
+ ```
316
+
317
+ ---
318
+
319
+ ## 강원특별자치도교육청도서관(gwe) 추가에서 확인된 사항
320
+
321
+ - **User-Agent 필수**: `lib.gwe.go.kr`는 User-Agent 없이 curl 하면 503바이트 오류 페이지 반환 (`해당 페이지는 오류가 발생했습니다`). `http.ts`의 `get()`은 자동 포함하지만 curl 분석 시 반드시 `-A "Mozilla/5.0 ..."` 추가
322
+ - **`analyze-html-library.sh list-codes` 사용 불가**: User-Agent 없이 실행되어 오류 페이지를 받음 → `curl -A "Mozilla/5.0" URL -o /tmp/file.html` 후 Python으로 직접 파싱
323
+ - **도서관 코드 파라미터**: `manageCodes` (체크박스 다중, 2자리 알파벳)
324
+ - **검색 파라미터**: `search=true`, `searchInput={title}`, `searchCondition=searchTxt`, `manageCodes={code}`, `size={N}`, `page=1` — GET 방식
325
+ - **총 건수**: 정규식 `검색결과\s*총\s*<strong>([\d,]+)<\/strong>건`
326
+ - **책 데이터**: `div.bookData`의 `data-title`, `data-reg-no`, `data-lib-name` data-* 속성
327
+ - **bookUrl**: `/portal/menu/568/book/view/{regNo}?booktype=` — User-Agent 없이도 접근 가능, 책 제목이 `<h4 class="book_detail__title">` 에 포함됨
328
+ - **대출 상태 없음**: 검색 결과에 대출 여부 미포함 (상세 페이지에만 존재) → `exist: false`
329
+ - **서버 하드 리밋 약 360건**: size=370 이상 오류 페이지 반환 → 안전값 300 (3.2초)
330
+ - **SSL 정상**: 체인 완전 (`*.gwe.go.kr` WISeKey 인증서)
331
+
332
+ ### gwe 도서관 코드 수집 (User-Agent 필수)
333
+
334
+ ```bash
335
+ curl -skL "https://lib.gwe.go.kr/portal/menu/568/book/search" \
336
+ -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
337
+ -o /tmp/gwe_search.html
338
+ python3 << 'EOF'
339
+ with open('/tmp/gwe_search.html', 'rb') as f:
340
+ html = f.read().decode('utf-8', errors='replace')
341
+ import re
342
+ # 중복 제거 후 출력
343
+ seen = set()
344
+ items = re.findall(
345
+ r'<input[^>]+value="([A-Z]+)"[^>]+name="manageCodes"[^/]*/>\s*<label[^>]*>([^<]+)</label>',
346
+ html
347
+ )
348
+ for code, name in items:
349
+ if code not in seen:
350
+ seen.add(code)
351
+ print(f' {{ code: "{code}", name: "{name.strip()}" }},')
352
+ EOF
353
+ ```
354
+
355
+ ---
356
+
357
+ ## 이번 시흥시도서관 추가에서 확인된 사항
358
+
359
+ - **pyxis 플랫폼 감지**: HTML에 `class="ikc-pyxis-wrap"` 또는 `ikc-pyxis-wrap` 클래스가 있으면 pyxis API 계열
360
+ - **전용 branches API**: `GET /pyxis-api/1/branches` → 전체 분관 목록 (id, name, branchGroup) 반환. 39개 분관 중 무인대출기(id 72, 82)는 제외하고 시립도서관 13개만 포함
361
+ - **SSL 인증서 불완전**: `lib.siheung.go.kr`는 중간 CA 누락 → `rejectUnauthorized: false` 필요
362
+ - **max 제한**: `max=1000`에서 52초 → `max=200`이 안전 (3초 이내)
363
+ - **SPA 처리**: Angular SPA라서 `/#/search/detail/{id}` URL은 JS 없이 렌더링 안 됨 → `SESSION_REQUIRED_DOMAINS`에 추가
364
+ - **totalBookCount**: pyxis 응답의 `data.totalCount` 사용 (max 제한으로 실제 결과가 잘리므로)
365
+
366
+ ---
367
+
368
+ ## 양천구도서관(yangcheon) 추가에서 확인된 사항 (nanum 플랫폼)
369
+
370
+ - **nanum 플랫폼 감지**: JS 경로에 `/nanum/site/` 패턴이 있으면 nanum 계열 (예: `/nanum/site/common/js/jquery-3.3.1.min.js`)
371
+ - **메인 리다이렉트**: `https://lib.yangcheon.or.kr` → JS `location.href="/main/main.do"` 로 리다이렉트
372
+ - **검색 엔드포인트**: `GET /main/site/search/bookSearch.do`
373
+ - **검색 파라미터**: `cmd_name=bookandnonbooksearch`, `manage_code={code}`, `search_key=ALL`, `search_txt={title}`, `rows=10`, `page={N}`
374
+ - **페이지 크기 고정**: `rows` 파라미터 무시 — 서버는 항상 10건/페이지 반환
375
+ - **총 건수 패턴**: `<span>전체 N</span>개가 검색되었습니다.` 정규식 `전체 ([\d,]+)<\/span>개가 검색되었습니다`
376
+ - **책 데이터**: `div.book_info` data-* 속성 — `data-ti`=제목, `data-rk`=species_key, `data-mgc`=도서관코드
377
+ - **reckey**: `data-rk`와 다름 — `p.tit > a`의 href에서 URLSearchParams로 `reckey` 파라미터를 추출해야 함
378
+ - **대출 상태**: `p.book_status span`의 class 확인 — `activity`=대출가능, `inactive`=불가
379
+ - **bookUrl**: `bookSearch.do?manage_code={mgc}&book_type=BOOK&book_type_org=&publish_form_code=MO&species_key={rk}&reckey={reckey}` — species_key와 reckey 모두 필요
380
+ - **SSL 정상**: 체인 완전 (Sectigo RSA)
381
+ - **WAF 차단**: "javascript" 검색어 → 0바이트 응답. "java" 검색어 사용 필요 → 테스트 spec에서 `{ englishSearchTerm: "java" }` 지정
@@ -0,0 +1,184 @@
1
+ # 전국 통합도서관 네트워크 목록
2
+
3
+ > `find-library` 도구로 추출한 통합도서관 네트워크 목록입니다.
4
+ > 같은 도메인을 공유하는 도서관이 2개 이상인 경우만 포함합니다.
5
+ > 위도·경도는 소속 도서관의 중심점(centroid)입니다.
6
+ > 생성일: 2026-05-04 | 총 173개 통합 네트워크 (1,965개 도서관)
7
+
8
+ **범례:** ✅ dongnelibrary 등록 완료
9
+
10
+ | # | 도메인 | 소속 도서관 수 | 대표 지역 | 유형 | 위도 | 경도 | 등록 |
11
+ |---|--------|:-----------:|---------|------|------|------|:----:|
12
+ | 1 | [smalllibrary.org](https://smalllibrary.org) | 121 | 광주광역시 | 작은도서관 | 35.025822 | 126.904679 | ✅ |
13
+ | 2 | [library.daegu.go.kr](https://library.daegu.go.kr) | 58 | 대구광역시 | 공공도서관 | 35.877406 | 128.604087 | ✅ |
14
+ | 3 | [lib.gimhae.go.kr](https://lib.gimhae.go.kr) | 48 | 경상남도 | 공공도서관 | 35.236396 | 128.83782 | |
15
+ | 4 | [phlib.pohang.go.kr](https://phlib.pohang.go.kr) | 48 | 경상북도 | 공공도서관 | 36.04163 | 129.371727 | |
16
+ | 5 | [snlib.go.kr](https://snlib.go.kr) | 40 | 경기도 | 공공도서관 | 37.411687 | 127.13204 | ✅ |
17
+ | 6 | [lib.gwanak.go.kr](https://lib.gwanak.go.kr) | 39 | 서울특별시 | 공공도서관 | 37.479283 | 126.9405 | ✅ |
18
+ | 7 | [lib.gangseo.seoul.kr](https://lib.gangseo.seoul.kr) | 36 | 서울특별시 | 공공도서관 | 37.552936 | 126.843157 | ✅ |
19
+ | 8 | [bcl.go.kr](https://bcl.go.kr) | 35 | 경기도 | 공공도서관 | 37.499971 | 126.784173 | |
20
+ | 9 | [nowonlib.kr](https://nowonlib.kr) | 34 | 서울특별시 | 공공도서관 | 37.644744 | 127.067109 | ✅ |
21
+ | 10 | [hscitylib.or.kr](https://hscitylib.or.kr) | 31 | 경기도 | 공공도서관 | 37.185136 | 126.962676 | ✅ |
22
+ | 11 | [lib.siheung.go.kr](https://lib.siheung.go.kr) | 31 | 경기도 | 공공도서관 | 37.384671 | 126.767317 | |
23
+ | 12 | [lib.geoje.go.kr](https://lib.geoje.go.kr) | 29 | 경상남도 | 공공도서관 | 34.878469 | 128.650711 | |
24
+ | 13 | [lib.jeju.go.kr](https://lib.jeju.go.kr) | 29 | 제주특별자치도 | 공공도서관 | 33.371201 | 126.534615 | ✅ |
25
+ | 14 | [library.gangnam.go.kr](https://library.gangnam.go.kr) | 27 | 서울특별시 | 공공도서관 | 37.495582 | 127.062791 | ✅ |
26
+ | 15 | [ydplib.or.kr](https://ydplib.or.kr) | 26 | 서울특별시 | 공공도서관 | 37.513016 | 126.905126 | ✅ |
27
+ | 16 | [gbelib.kr](https://gbelib.kr) | 24 | 경상북도 | 공공도서관 | 36.395037 | 128.809928 | |
28
+ | 17 | [lib.gwe.go.kr](https://lib.gwe.go.kr) | 24 | 강원특별자치도 | 공공도서관 | 37.734348 | 128.301995 | |
29
+ | 18 | [lib.ansan.go.kr](https://lib.ansan.go.kr) | 24 | 경기도 | 공공도서관 | 37.318173 | 126.8226 | |
30
+ | 19 | [suwonlib.go.kr](https://suwonlib.go.kr) | 23 | 경기도 | 공공도서관 | 37.272295 | 127.020091 | ✅ |
31
+ | 20 | [lib.yangcheon.or.kr](https://lib.yangcheon.or.kr) | 23 | 서울특별시 | 공공도서관 | 37.525064 | 126.853829 | |
32
+ | 21 | [lib.gunsan.go.kr](https://lib.gunsan.go.kr) | 22 | 전북특별자치도 | 공공도서관 | 35.96941 | 126.727303 | |
33
+ | 22 | [mokpolib.or.kr](https://mokpolib.or.kr) | 22 | 전라남도 | 공공도서관 | 34.804333 | 126.402538 | |
34
+ | 23 | [lib.dgs.go.kr](https://lib.dgs.go.kr) | 22 | 대구광역시 | 공공도서관 | 35.873767 | 128.558757 | |
35
+ | 24 | [lib.paju.go.kr](https://lib.paju.go.kr) | 22 | 경기도 | 공공도서관 | 37.792681 | 126.787374 | |
36
+ | 25 | [namwon.go.kr](https://namwon.go.kr) | 21 | 전북특별자치도 | 공공도서관 | 35.425757 | 127.421661 | |
37
+ | 26 | [lib.yongin.go.kr](https://lib.yongin.go.kr) | 20 | 경기도 | 공공도서관 | 37.27137 | 127.139799 | ✅ |
38
+ | 27 | [cheonan.go.kr](https://cheonan.go.kr) | 20 | 충청남도 | 공공도서관 | 36.798737 | 127.166065 | |
39
+ | 28 | [lib.jbe.go.kr](https://lib.jbe.go.kr) | 19 | 전북특별자치도 | 공공도서관 | 35.739328 | 127.122167 | |
40
+ | 29 | [junggulib.or.kr](https://junggulib.or.kr) | 19 | 서울특별시 | 공공도서관 | 37.558735 | 127.004214 | |
41
+ | 30 | [goyanglib.or.kr](https://goyanglib.or.kr) | 18 | 경기도 | 공공도서관 | 37.664976 | 126.811196 | |
42
+ | 31 | [uilib.go.kr](https://uilib.go.kr) | 18 | 경기도 | 공공도서관 | 37.739667 | 127.058659 | |
43
+ | 32 | [sblib.seoul.kr](https://sblib.seoul.kr) | 17 | 서울특별시 | 공공도서관 | 37.603459 | 127.027155 | |
44
+ | 33 | [yspubliclib.go.kr](https://yspubliclib.go.kr) | 17 | 인천광역시 | 공공도서관 | 37.408622 | 126.664447 | |
45
+ | 34 | [lib.gjcity.go.kr](https://lib.gjcity.go.kr) | 16 | 경기도 | 공공도서관 | 37.391618 | 127.260101 | ✅ |
46
+ | 35 | [busanjin.go.kr](https://busanjin.go.kr) | 16 | 부산광역시 | 공공도서관 | 35.161358 | 129.049921 | |
47
+ | 36 | [lib.yuseong.go.kr](https://lib.yuseong.go.kr) | 16 | 대전광역시 | 공공도서관 | 36.372348 | 127.346007 | |
48
+ | 37 | [saha.go.kr](https://saha.go.kr) | 16 | 부산광역시 | 공공도서관 | 35.091668 | 128.981518 | |
49
+ | 38 | [geumcheonlib.seoul.kr](https://geumcheonlib.seoul.kr) | 16 | 서울특별시 | 공공도서관 | 37.462239 | 126.900608 | |
50
+ | 39 | [yslibrary.or.kr](https://yslibrary.or.kr) | 16 | 서울특별시 | 공공도서관 | 37.536474 | 126.975599 | |
51
+ | 40 | [home.pen.go.kr](https://home.pen.go.kr) | 15 | 부산광역시 | 공공도서관 | 35.167713 | 129.07503 | |
52
+ | 41 | [lib.sdm.or.kr](https://lib.sdm.or.kr) | 15 | 서울특별시 | 공공도서관 | 37.579301 | 126.941944 | |
53
+ | 42 | [lib.sejong.go.kr](https://lib.sejong.go.kr) | 15 | 세종특별자치시 | 공공도서관 | 36.498952 | 127.26564 | |
54
+ | 43 | [lib.jongno.go.kr](https://lib.jongno.go.kr) | 15 | 서울특별시 | 공공도서관 | 37.581579 | 126.988663 | |
55
+ | 44 | [mplib.mapo.go.kr](https://mplib.mapo.go.kr) | 15 | 서울특별시 | 공공도서관 | 37.554554 | 126.928888 | |
56
+ | 45 | [lib.guro.go.kr](https://lib.guro.go.kr) | 14 | 서울특별시 | 공공도서관 | 37.497106 | 126.864936 | |
57
+ | 46 | [library.cheongju.go.kr](https://library.cheongju.go.kr) | 14 | 충청북도 | 공공도서관 | 36.653571 | 127.446406 | |
58
+ | 47 | [ptlib.go.kr](https://ptlib.go.kr) | 14 | 경기도 | 공공도서관 | 37.022243 | 127.033669 | ✅ |
59
+ | 48 | [uwlib.or.kr](https://uwlib.or.kr) | 13 | 경기도 | 공공도서관 | 37.364248 | 126.978384 | ✅ |
60
+ | 49 | [lib.nyj.go.kr](https://lib.nyj.go.kr) | 13 | 경기도 | 공공도서관 | 37.663256 | 127.201767 | |
61
+ | 50 | [uljulib.ulju.ulsan.kr](https://uljulib.ulju.ulsan.kr) | 13 | 울산광역시 | 공공도서관 | 35.496313 | 129.222678 | |
62
+ | 51 | [smalllib.gwangjin.go.kr](https://smalllib.gwangjin.go.kr) | 12 | 서울특별시 | 작은도서관 | 37.547982 | 127.08137 | |
63
+ | 52 | [lib.jeonju.go.kr](https://lib.jeonju.go.kr) | 12 | 전북특별자치도 | 공공도서관 | 35.82991 | 127.130449 | |
64
+ | 53 | [donggu.go.kr](https://donggu.go.kr) | 12 | 대전광역시 | 공공도서관 | 36.32649 | 127.452255 | |
65
+ | 54 | [bppl.or.kr](https://bppl.or.kr) | 12 | 인천광역시 | 공공도서관 | 37.498033 | 126.725449 | |
66
+ | 55 | [lib.changwon.go.kr](https://lib.changwon.go.kr) | 12 | 경상남도 | 공공도서관 | 35.219253 | 128.630898 | |
67
+ | 56 | [yplib.go.kr](https://yplib.go.kr) | 12 | 경기도 | 공공도서관 | 37.503595 | 127.534649 | ✅ |
68
+ | 57 | [lib.anyang.go.kr](https://lib.anyang.go.kr) | 11 | 경기도 | 공공도서관 | 37.394896 | 126.938568 | |
69
+ | 58 | [lib.wanju.go.kr](https://lib.wanju.go.kr) | 11 | 전북특별자치도 | 공공도서관 | 35.894323 | 127.152602 | |
70
+ | 59 | [hnrl.michu.incheon.kr](https://hnrl.michu.incheon.kr) | 11 | 인천광역시 | 공공도서관 | 37.458069 | 126.669274 | |
71
+ | 60 | [lib.junggu.ulsan.kr](https://lib.junggu.ulsan.kr) | 11 | 울산광역시 | 공공도서관 | 35.564763 | 129.324589 | |
72
+ | 61 | [splib.or.kr](https://splib.or.kr) | 11 | 서울특별시 | 공공도서관 | 37.502352 | 127.115717 | |
73
+ | 62 | [lib.dongjak.go.kr](https://lib.dongjak.go.kr) | 11 | 서울특별시 | 공공도서관 | 37.495286 | 126.94618 | |
74
+ | 63 | [gbmg.go.kr](https://gbmg.go.kr) | 10 | 경상북도 | 공공도서관 | 36.645716 | 128.188876 | |
75
+ | 64 | [gcl.go.kr](https://gcl.go.kr) | 10 | 경상북도 | 공공도서관 | 36.137028 | 128.137822 | |
76
+ | 65 | [seogu.go.kr](https://seogu.go.kr) | 10 | 대전광역시 | 공공도서관 | 36.332927 | 127.369688 | |
77
+ | 66 | [lib.hsg.go.kr](https://lib.hsg.go.kr) | 10 | 강원특별자치도 | 공공도서관 | 37.489304 | 128.05986 | |
78
+ | 67 | [libyj.go.kr](https://libyj.go.kr) | 10 | 경기도 | 공공도서관 | 37.813729 | 127.03849 | |
79
+ | 68 | [lib.gumi.go.kr](https://lib.gumi.go.kr) | 10 | 경상북도 | 공공도서관 | 36.143549 | 128.366111 | |
80
+ | 69 | [yjlib.go.kr](https://yjlib.go.kr) | 9 | 경기도 | 공공도서관 | 37.324591 | 127.588986 | ✅ |
81
+ | 70 | [lib.jung.daegu.kr](https://lib.jung.daegu.kr) | 9 | 대구광역시 | 작은도서관 | 35.865476 | 128.596042 | |
82
+ | 71 | [small.u-library.kr](https://small.u-library.kr) | 9 | 대전광역시 | 공공도서관 | 36.378606 | 127.353503 | |
83
+ | 72 | [lib.ice.go.kr](https://lib.ice.go.kr) | 9 | 인천광역시 | 공공도서관 | 37.483273 | 126.69674 | ✅ |
84
+ | 73 | [library.geumsan.go.kr](https://library.geumsan.go.kr) | 9 | 충청남도 | 공공도서관 | 36.114213 | 127.480668 | |
85
+ | 74 | [usbl.bukgu.ulsan.kr](https://usbl.bukgu.ulsan.kr) | 9 | 울산광역시 | 공공도서관 | 35.608119 | 129.367099 | |
86
+ | 75 | [lib.uljin.go.kr](https://lib.uljin.go.kr) | 9 | 경상북도 | 공공도서관 | 36.886441 | 129.405962 | |
87
+ | 76 | [brcn.go.kr](https://brcn.go.kr) | 9 | 충청남도 | 공공도서관 | 36.347133 | 126.596203 | |
88
+ | 77 | [hanamlib.go.kr](https://hanamlib.go.kr) | 8 | 경기도 | 공공도서관 | 37.542404 | 127.191655 | ✅ |
89
+ | 78 | [lib.goe.go.kr](https://lib.goe.go.kr) | 8 | 경기도 | 공공도서관 | 37.36146 | 127.009427 | ✅ |
90
+ | 79 | [seosan.go.kr](https://seosan.go.kr) | 8 | 충청남도 | 공공도서관 | 36.785429 | 126.467097 | |
91
+ | 80 | [library.chuncheon.go.kr](https://library.chuncheon.go.kr) | 8 | 강원특별자치도 | 공공도서관 | 37.866401 | 127.721662 | |
92
+ | 81 | [unilib.dobong.kr](https://unilib.dobong.kr) | 8 | 서울특별시 | 공공도서관 | 37.65917 | 127.041834 | |
93
+ | 82 | [gurilib.go.kr](https://gurilib.go.kr) | 8 | 경기도 | 공공도서관 | 37.600456 | 127.136467 | |
94
+ | 83 | [gnslib.or.kr](https://gnslib.or.kr) | 8 | 강원특별자치도 | 공공도서관 | 37.763821 | 128.905442 | |
95
+ | 84 | [gunpolib.go.kr](https://gunpolib.go.kr) | 7 | 경기도 | 공공도서관 | 37.347571 | 126.929514 | ✅ |
96
+ | 85 | [pc.go.kr](https://pc.go.kr) | 7 | 강원특별자치도 | 공공도서관 | 37.544467 | 128.474428 | |
97
+ | 86 | [osanlibrary.go.kr](https://osanlibrary.go.kr) | 7 | 경기도 | 공공도서관 | 37.156869 | 127.058883 | ✅ |
98
+ | 87 | [yeonje.go.kr](https://yeonje.go.kr) | 7 | 부산광역시 | 공공도서관 | 35.178148 | 129.087008 | |
99
+ | 88 | [library.gijang.go.kr](https://library.gijang.go.kr) | 7 | 부산광역시 | 공공도서관 | 35.262193 | 129.196757 | |
100
+ | 89 | [lib.iksan.go.kr](https://lib.iksan.go.kr) | 7 | 전북특별자치도 | 공공도서관 | 35.963415 | 126.977715 | |
101
+ | 90 | [lib.pocheon.go.kr](https://lib.pocheon.go.kr) | 7 | 경기도 | 공공도서관 | 37.926855 | 127.21781 | |
102
+ | 91 | [yslib.yeosu.go.kr](https://yslib.yeosu.go.kr) | 7 | 전라남도 | 공공도서관 | 34.773185 | 127.677747 | ✅ |
103
+ | 92 | [ascl.asan.go.kr](https://ascl.asan.go.kr) | 7 | 충청남도 | 공공도서관 | 36.810605 | 127.044635 | ✅ |
104
+ | 93 | [gblib.or.kr](https://gblib.or.kr) | 7 | 서울특별시 | 공공도서관 | 37.622762 | 127.023613 | |
105
+ | 94 | [lib.buan.go.kr](https://lib.buan.go.kr) | 7 | 전북특별자치도 | 공공도서관 | 35.665928 | 126.60544 | |
106
+ | 95 | [sdlib.or.kr](https://sdlib.or.kr) | 7 | 서울특별시 | 공공도서관 | 37.557487 | 127.033075 | |
107
+ | 96 | [gygl.go.kr](https://gygl.go.kr) | 6 | 인천광역시 | 공공도서관 | 37.537352 | 126.732599 | |
108
+ | 97 | [donghaelib.go.kr](https://donghaelib.go.kr) | 6 | 강원특별자치도 | 공공도서관 | 37.51531 | 129.103322 | |
109
+ | 98 | [gwangjinlib.seoul.kr](https://gwangjinlib.seoul.kr) | 6 | 서울특별시 | 공공도서관 | 37.545949 | 127.084466 | |
110
+ | 99 | [lib.gen.go.kr](https://lib.gen.go.kr) | 6 | 광주광역시 | 공공도서관 | 35.153913 | 126.874534 | |
111
+ | 100 | [library.seogu.gwangju.kr](https://library.seogu.gwangju.kr) | 6 | 광주광역시 | 공공도서관 | 35.150019 | 126.87312 | |
112
+ | 101 | [library.gyeongju.go.kr](https://library.gyeongju.go.kr) | 6 | 경상북도 | 공공도서관 | 35.863929 | 129.237195 | |
113
+ | 102 | [ulsannamgu.go.kr](https://ulsannamgu.go.kr) | 6 | 울산광역시 | 공공도서관 | 35.5415 | 129.29109 | |
114
+ | 103 | [lib.ddc.go.kr](https://lib.ddc.go.kr) | 6 | 경기도 | 공공도서관 | 37.904467 | 127.055123 | |
115
+ | 104 | [lib.daedeok.go.kr](https://lib.daedeok.go.kr) | 6 | 대전광역시 | 공공도서관 | 36.392345 | 127.432537 | |
116
+ | 105 | [yanggu.go.kr](https://yanggu.go.kr) | 6 | 강원특별자치도 | 작은도서관 | 38.168168 | 128.022324 | |
117
+ | 106 | [gmlib.gm.go.kr](https://gmlib.gm.go.kr) | 6 | 경기도 | 공공도서관 | 37.462068 | 126.872452 | |
118
+ | 107 | [gimpo.go.kr](https://gimpo.go.kr) | 6 | 경기도 | 공공도서관 | 37.641884 | 126.673386 | |
119
+ | 108 | [haeundae.go.kr](https://haeundae.go.kr) | 6 | 부산광역시 | 공공도서관 | 35.188482 | 129.140611 | |
120
+ | 109 | [org.jje.go.kr](https://org.jje.go.kr) | 6 | 제주특별자치도 | 공공도서관 | 33.367801 | 126.529914 | |
121
+ | 110 | [library.suncheon.go.kr](https://library.suncheon.go.kr) | 6 | 전라남도 | 공공도서관 | 34.952289 | 127.514904 | |
122
+ | 111 | [lib.andong.go.kr](https://lib.andong.go.kr) | 6 | 경상북도 | 공공도서관 | 36.569776 | 128.733936 | |
123
+ | 112 | [lib.gwangyang.go.kr](https://lib.gwangyang.go.kr) | 6 | 전라남도 | 공공도서관 | 34.960979 | 127.65189 | |
124
+ | 113 | [gdlibrary.or.kr](https://gdlibrary.or.kr) | 6 | 서울특별시 | 공공도서관 | 37.544484 | 127.141428 | |
125
+ | 114 | [lib.gwangsan.go.kr](https://lib.gwangsan.go.kr) | 5 | 광주광역시 | 공공도서관 | 35.181762 | 126.815005 | |
126
+ | 115 | [lib.yangsan.go.kr](https://lib.yangsan.go.kr) | 5 | 경상남도 | 공공도서관 | 35.337993 | 129.051285 | |
127
+ | 116 | [lib.bukgu.gwangju.kr](https://lib.bukgu.gwangju.kr) | 5 | 광주광역시 | 공공도서관 | 35.193475 | 126.884097 | |
128
+ | 117 | [suyeong.go.kr](https://suyeong.go.kr) | 5 | 부산광역시 | 공공도서관 | 35.161864 | 129.108347 | |
129
+ | 118 | [bsbukgu.go.kr](https://bsbukgu.go.kr) | 5 | 부산광역시 | 공공도서관 | 35.231414 | 129.023976 | |
130
+ | 119 | [jungnanglib.seoul.kr](https://jungnanglib.seoul.kr) | 5 | 서울특별시 | 공공도서관 | 37.60099 | 127.093988 | |
131
+ | 120 | [lib.donggu.kr](https://lib.donggu.kr) | 5 | 광주광역시 | 공공도서관 | 35.130654 | 126.933136 | |
132
+ | 121 | [library.chilgok.go.kr](https://library.chilgok.go.kr) | 5 | 경상북도 | 공공도서관 | 36.025773 | 128.413566 | |
133
+ | 122 | [namdonglib.go.kr](https://namdonglib.go.kr) | 5 | 인천광역시 | 공공도서관 | 37.43189 | 126.728346 | |
134
+ | 123 | [citylib.gwangju.go.kr](https://citylib.gwangju.go.kr) | 5 | 광주광역시 | 공공도서관 | 35.152792 | 126.919712 | |
135
+ | 124 | [lib.yeongju.go.kr](https://lib.yeongju.go.kr) | 5 | 경상북도 | 공공도서관 | 36.810266 | 128.63615 | |
136
+ | 125 | [icheonlib.go.kr](https://icheonlib.go.kr) | 5 | 경기도 | 공공도서관 | 37.239419 | 127.465173 | |
137
+ | 126 | [library.muju.go.kr](https://library.muju.go.kr) | 4 | 전북특별자치도 | 작은도서관 | 35.93805 | 127.684377 | |
138
+ | 127 | [lib.eumseong.go.kr](https://lib.eumseong.go.kr) | 4 | 충청북도 | 공공도서관 | 37.005223 | 127.541194 | |
139
+ | 128 | [jecheon.go.kr](https://jecheon.go.kr) | 4 | 충청북도 | 공공도서관 | 37.140339 | 128.193864 | |
140
+ | 129 | [lib.cheongdo.go.kr](https://lib.cheongdo.go.kr) | 4 | 경상북도 | 어린이도서관 | 35.66137 | 128.728595 | |
141
+ | 130 | [lib.wonju.go.kr](https://lib.wonju.go.kr) | 4 | 강원특별자치도 | 공공도서관 | 37.325627 | 127.939737 | ✅ |
142
+ | 131 | [library.bsgangseo.go.kr](https://library.bsgangseo.go.kr) | 4 | 부산광역시 | 공공도서관 | 35.126494 | 128.89144 | |
143
+ | 132 | [tongyeonglib.or.kr](https://tongyeonglib.or.kr) | 4 | 경상남도 | 공공도서관 | 34.793587 | 128.375517 | |
144
+ | 133 | [lib.namgu.gwangju.kr](https://lib.namgu.gwangju.kr) | 4 | 광주광역시 | 공공도서관 | 35.119158 | 126.903522 | |
145
+ | 134 | [gaplib.go.kr](https://gaplib.go.kr) | 4 | 경기도 | 공공도서관 | 37.767722 | 127.443665 | |
146
+ | 135 | [myclib.or.kr](https://myclib.or.kr) | 3 | 경상남도 | 공공도서관 | 35.508958 | 128.738002 | |
147
+ | 136 | [seogu.gwangju.kr](https://seogu.gwangju.kr) | 3 | 광주광역시 | 공공도서관 | 35.130548 | 126.874265 | |
148
+ | 137 | [cwglib.cwg.go.kr](https://cwglib.cwg.go.kr) | 3 | 강원특별자치도 | 공공도서관 | 38.200839 | 127.319756 | |
149
+ | 138 | [yeongam.go.kr](https://yeongam.go.kr) | 3 | 전라남도 | 공공도서관 | 34.756352 | 126.575812 | |
150
+ | 139 | [lib.icdonggu.go.kr](https://lib.icdonggu.go.kr) | 3 | 인천광역시 | 공공도서관 | 37.475462 | 126.647227 | |
151
+ | 140 | [lib.inje.go.kr](https://lib.inje.go.kr) | 3 | 강원특별자치도 | 공공도서관 | 38.100843 | 128.243907 | |
152
+ | 141 | [sasang.go.kr](https://sasang.go.kr) | 3 | 부산광역시 | 공공도서관 | 35.160214 | 128.993696 | |
153
+ | 142 | [lib.nonsan.go.kr](https://lib.nonsan.go.kr) | 3 | 충청남도 | 공공도서관 | 36.160644 | 127.074311 | |
154
+ | 143 | [lib.ganghwa.go.kr](https://lib.ganghwa.go.kr) | 3 | 인천광역시 | 공공도서관 | 37.730324 | 126.452029 | |
155
+ | 144 | [dblib.sen.go.kr](https://dblib.sen.go.kr) | 3 | 서울특별시 | 공공도서관 | 37.652634 | 127.01295 | |
156
+ | 145 | [lib.jangseong.go.kr](https://lib.jangseong.go.kr) | 3 | 전라남도 | 공공도서관 | 35.329905 | 126.746749 | |
157
+ | 146 | [lib.jincheon.go.kr](https://lib.jincheon.go.kr) | 3 | 충청북도 | 공공도서관 | 36.916683 | 127.467325 | |
158
+ | 147 | [lib.jeongeup.go.kr](https://lib.jeongeup.go.kr) | 3 | 전북특별자치도 | 공공도서관 | 35.610466 | 126.872536 | |
159
+ | 148 | [kisingo.or.kr](https://kisingo.or.kr) | 3 | 경상남도 | 작은도서관 | 35.238269 | 128.670549 | |
160
+ | 149 | [dylib.jne.go.kr](https://dylib.jne.go.kr) | 2 | 전라남도 | 공공도서관 | 35.312082 | 126.98395 | |
161
+ | 150 | [gylife.jne.go.kr](https://gylife.jne.go.kr) | 2 | 전라남도 | 공공도서관 | 34.954706 | 127.704178 | |
162
+ | 151 | [library.yeoncheon.go.kr](https://library.yeoncheon.go.kr) | 2 | 경기도 | 공공도서관 | 38.065218 | 127.073837 | |
163
+ | 152 | [gselib.go.kr](https://gselib.go.kr) | 2 | 충청북도 | 공공도서관 | 36.811057 | 127.792179 | |
164
+ | 153 | [gjlib.gne.go.kr](https://gjlib.gne.go.kr) | 2 | 경상남도 | 공공도서관 | 34.878998 | 128.622898 | |
165
+ | 154 | [library.sokcho.go.kr](https://library.sokcho.go.kr) | 2 | 강원특별자치도 | 공공도서관 | 38.196585 | 128.581239 | |
166
+ | 155 | [lib.naju.go.kr](https://lib.naju.go.kr) | 2 | 전라남도 | 공공도서관 | 35.010411 | 126.749807 | |
167
+ | 156 | [usdl.or.kr](https://usdl.or.kr) | 2 | 울산광역시 | 공공도서관 | 35.528204 | 129.425051 | |
168
+ | 157 | [eplib.or.kr](https://eplib.or.kr) | 2 | 서울특별시 | 공공도서관 | 37.625353 | 126.922791 | |
169
+ | 158 | [hclib.or.kr](https://hclib.or.kr) | 2 | 강원특별자치도 | 공공도서관 | 38.08881 | 127.611657 | |
170
+ | 159 | [yeongdo.go.kr](https://yeongdo.go.kr) | 2 | 부산광역시 | 공공도서관 | 35.08191 | 129.052954 | |
171
+ | 160 | [lib.sacheon.go.kr](https://lib.sacheon.go.kr) | 2 | 경상남도 | 공공도서관 | 35.06532 | 128.074136 | |
172
+ | 161 | [urlib.gne.go.kr](https://urlib.gne.go.kr) | 2 | 경상남도 | 공공도서관 | 35.319717 | 128.266728 | |
173
+ | 162 | [taebaek.go.kr](https://taebaek.go.kr) | 2 | 강원특별자치도 | 공공도서관 | 37.139837 | 129.003462 | |
174
+ | 163 | [ysplib.go.kr](https://ysplib.go.kr) | 2 | 충청남도 | 공공도서관 | 36.695853 | 126.792049 | |
175
+ | 164 | [lib.dongnae.go.kr](https://lib.dongnae.go.kr) | 2 | 부산광역시 | 공공도서관 | 35.202076 | 129.101243 | |
176
+ | 165 | [gongjulib.go.kr](https://gongjulib.go.kr) | 2 | 충청남도 | 공공도서관 | 36.466036 | 127.132973 | |
177
+ | 166 | [gwgs.go.kr](https://gwgs.go.kr) | 2 | 강원특별자치도 | 공공도서관 | 38.320012 | 128.509931 | |
178
+ | 167 | [lib.gyeryong.go.kr](https://lib.gyeryong.go.kr) | 2 | 충청남도 | 공공도서관 | 36.281973 | 127.243868 | |
179
+ | 168 | [gclib.go.kr](https://gclib.go.kr) | 2 | 경기도 | 공공도서관 | 37.421842 | 126.998567 | |
180
+ | 169 | [doccic.go.kr](https://doccic.go.kr) | 2 | 서울특별시 | 공공도서관 | 37.64837 | 127.035715 | |
181
+ | 170 | [danyang.go.kr](https://danyang.go.kr) | 2 | 충청북도 | 공공도서관 | 37.009488 | 128.330097 | |
182
+ | 171 | [bsdonggu.go.kr](https://bsdonggu.go.kr) | 2 | 부산광역시 | 공공도서관 | 35.136345 | 129.047211 | |
183
+ | 172 | [taean.go.kr](https://taean.go.kr) | 2 | 충청남도 | 공공도서관 | 36.635229 | 126.328519 | |
184
+ | 173 | [swsilver.org](https://swsilver.org) | 2 | 전북특별자치도 | 작은도서관 | 35.813988 | 127.142259 | |
@@ -9,35 +9,35 @@
9
9
 
10
10
  | # | 도메인 | 소속 도서관 수 | 대표 지역 | 유형 | 위도 | 경도 | 등록 |
11
11
  |---|--------|:-----------:|---------|------|------|------|:----:|
12
- | 1 | [smalllibrary.org](https://smalllibrary.org) | 121 | 광주광역시 | 작은도서관 | 35.025822 | 126.904679 | |
12
+ | 1 | [smalllibrary.org](https://smalllibrary.org) | 121 | 광주광역시 | 작은도서관 | 35.025822 | 126.904679 ||
13
13
  | 2 | [library.daegu.go.kr](https://library.daegu.go.kr) | 58 | 대구광역시 | 공공도서관 | 35.877406 | 128.604087 | ✅ |
14
- | 3 | [lib.gimhae.go.kr](https://lib.gimhae.go.kr) | 48 | 경상남도 | 공공도서관 | 35.236396 | 128.83782 | |
15
- | 4 | [phlib.pohang.go.kr](https://phlib.pohang.go.kr) | 48 | 경상북도 | 공공도서관 | 36.04163 | 129.371727 | |
14
+ | 3 | [lib.gimhae.go.kr](https://lib.gimhae.go.kr) | 48 | 경상남도 | 공공도서관 | 35.236396 | 128.83782 ||
15
+ | 4 | [phlib.pohang.go.kr](https://phlib.pohang.go.kr) | 48 | 경상북도 | 공공도서관 | 36.04163 | 129.371727 ||
16
16
  | 5 | [snlib.go.kr](https://snlib.go.kr) | 40 | 경기도 | 공공도서관 | 37.411687 | 127.13204 | ✅ |
17
- | 6 | [lib.gwanak.go.kr](https://lib.gwanak.go.kr) | 39 | 서울특별시 | 공공도서관 | 37.479283 | 126.9405 | |
18
- | 7 | [lib.gangseo.seoul.kr](https://lib.gangseo.seoul.kr) | 36 | 서울특별시 | 공공도서관 | 37.552936 | 126.843157 | |
19
- | 8 | [bcl.go.kr](https://bcl.go.kr) | 35 | 경기도 | 공공도서관 | 37.499971 | 126.784173 | |
20
- | 9 | [nowonlib.kr](https://nowonlib.kr) | 34 | 서울특별시 | 공공도서관 | 37.644744 | 127.067109 | |
17
+ | 6 | [lib.gwanak.go.kr](https://lib.gwanak.go.kr) | 39 | 서울특별시 | 공공도서관 | 37.479283 | 126.9405 ||
18
+ | 7 | [lib.gangseo.seoul.kr](https://lib.gangseo.seoul.kr) | 36 | 서울특별시 | 공공도서관 | 37.552936 | 126.843157 ||
19
+ | 8 | [bcl.go.kr](https://bcl.go.kr) | 35 | 경기도 | 공공도서관 | 37.499971 | 126.784173 ||
20
+ | 9 | [nowonlib.kr](https://nowonlib.kr) | 34 | 서울특별시 | 공공도서관 | 37.644744 | 127.067109 ||
21
21
  | 10 | [hscitylib.or.kr](https://hscitylib.or.kr) | 31 | 경기도 | 공공도서관 | 37.185136 | 126.962676 | ✅ |
22
- | 11 | [lib.siheung.go.kr](https://lib.siheung.go.kr) | 31 | 경기도 | 공공도서관 | 37.384671 | 126.767317 | |
23
- | 12 | [lib.geoje.go.kr](https://lib.geoje.go.kr) | 29 | 경상남도 | 공공도서관 | 34.878469 | 128.650711 | |
22
+ | 11 | [lib.siheung.go.kr](https://lib.siheung.go.kr) | 31 | 경기도 | 공공도서관 | 37.384671 | 126.767317 ||
23
+ | 12 | [lib.geoje.go.kr](https://lib.geoje.go.kr) | 29 | 경상남도 | 공공도서관 | 34.878469 | 128.650711 ||
24
24
  | 13 | [lib.jeju.go.kr](https://lib.jeju.go.kr) | 29 | 제주특별자치도 | 공공도서관 | 33.371201 | 126.534615 | ✅ |
25
- | 14 | [library.gangnam.go.kr](https://library.gangnam.go.kr) | 27 | 서울특별시 | 공공도서관 | 37.495582 | 127.062791 | |
26
- | 15 | [ydplib.or.kr](https://ydplib.or.kr) | 26 | 서울특별시 | 공공도서관 | 37.513016 | 126.905126 | |
27
- | 16 | [gbelib.kr](https://gbelib.kr) | 24 | 경상북도 | 공공도서관 | 36.395037 | 128.809928 | |
28
- | 17 | [lib.gwe.go.kr](https://lib.gwe.go.kr) | 24 | 강원특별자치도 | 공공도서관 | 37.734348 | 128.301995 | |
29
- | 18 | [lib.ansan.go.kr](https://lib.ansan.go.kr) | 24 | 경기도 | 공공도서관 | 37.318173 | 126.8226 | |
25
+ | 14 | [library.gangnam.go.kr](https://library.gangnam.go.kr) | 27 | 서울특별시 | 공공도서관 | 37.495582 | 127.062791 ||
26
+ | 15 | [ydplib.or.kr](https://ydplib.or.kr) | 26 | 서울특별시 | 공공도서관 | 37.513016 | 126.905126 ||
27
+ | 16 | [gbelib.kr](https://gbelib.kr) | 24 | 경상북도 | 공공도서관 | 36.395037 | 128.809928 ||
28
+ | 17 | [lib.gwe.go.kr](https://lib.gwe.go.kr) | 24 | 강원특별자치도 | 공공도서관 | 37.734348 | 128.301995 ||
29
+ | 18 | [lib.ansan.go.kr](https://lib.ansan.go.kr) | 24 | 경기도 | 공공도서관 | 37.318173 | 126.8226 ||
30
30
  | 19 | [suwonlib.go.kr](https://suwonlib.go.kr) | 23 | 경기도 | 공공도서관 | 37.272295 | 127.020091 | ✅ |
31
- | 20 | [lib.yangcheon.or.kr](https://lib.yangcheon.or.kr) | 23 | 서울특별시 | 공공도서관 | 37.525064 | 126.853829 | |
32
- | 21 | [lib.gunsan.go.kr](https://lib.gunsan.go.kr) | 22 | 전북특별자치도 | 공공도서관 | 35.96941 | 126.727303 | |
33
- | 22 | [mokpolib.or.kr](https://mokpolib.or.kr) | 22 | 전라남도 | 공공도서관 | 34.804333 | 126.402538 | |
31
+ | 20 | [lib.yangcheon.or.kr](https://lib.yangcheon.or.kr) | 23 | 서울특별시 | 공공도서관 | 37.525064 | 126.853829 ||
32
+ | 21 | [lib.gunsan.go.kr](https://lib.gunsan.go.kr) | 22 | 전북특별자치도 | 공공도서관 | 35.96941 | 126.727303 ||
33
+ | 22 | [mokpolib.or.kr](https://mokpolib.or.kr) | 23 | 전라남도 | 공공도서관 | 34.804333 | 126.402538 ||
34
34
  | 23 | [lib.dgs.go.kr](https://lib.dgs.go.kr) | 22 | 대구광역시 | 공공도서관 | 35.873767 | 128.558757 | |
35
- | 24 | [lib.paju.go.kr](https://lib.paju.go.kr) | 22 | 경기도 | 공공도서관 | 37.792681 | 126.787374 | |
35
+ | 24 | [lib.paju.go.kr](https://lib.paju.go.kr) | 22 | 경기도 | 공공도서관 | 37.792681 | 126.787374 ||
36
36
  | 25 | [namwon.go.kr](https://namwon.go.kr) | 21 | 전북특별자치도 | 공공도서관 | 35.425757 | 127.421661 | |
37
37
  | 26 | [lib.yongin.go.kr](https://lib.yongin.go.kr) | 20 | 경기도 | 공공도서관 | 37.27137 | 127.139799 | ✅ |
38
38
  | 27 | [cheonan.go.kr](https://cheonan.go.kr) | 20 | 충청남도 | 공공도서관 | 36.798737 | 127.166065 | |
39
39
  | 28 | [lib.jbe.go.kr](https://lib.jbe.go.kr) | 19 | 전북특별자치도 | 공공도서관 | 35.739328 | 127.122167 | |
40
- | 29 | [junggulib.or.kr](https://junggulib.or.kr) | 19 | 서울특별시 | 공공도서관 | 37.558735 | 127.004214 | |
40
+ | 29 | [junggulib.or.kr](https://junggulib.or.kr) | 19 | 서울특별시 | 공공도서관 | 37.558735 | 127.004214 ||
41
41
  | 30 | [goyanglib.or.kr](https://goyanglib.or.kr) | 18 | 경기도 | 공공도서관 | 37.664976 | 126.811196 | |
42
42
  | 31 | [uilib.go.kr](https://uilib.go.kr) | 18 | 경기도 | 공공도서관 | 37.739667 | 127.058659 | |
43
43
  | 32 | [sblib.seoul.kr](https://sblib.seoul.kr) | 17 | 서울특별시 | 공공도서관 | 37.603459 | 127.027155 | |