Skip to content

Instantly share code, notes, and snippets.

@benelog
Last active April 22, 2026 14:16
Show Gist options
  • Select an option

  • Save benelog/1fc18fc5859d3afbba9a20fa68fda744 to your computer and use it in GitHub Desktop.

Select an option

Save benelog/1fc18fc5859d3afbba9a20fa68fda744 to your computer and use it in GitHub Desktop.
연세대 ibook 뷰어에서 책을 PDF로 다운로드

View to PDF

연세대 ibook 뷰어(https://ibook.yonsei.ac.kr)에서 책을 PDF로 다운로드합니다.

필요 환경

  • Python 3
  • img2pdf (pip install img2pdf)

사용법

./download-ibook.py https://ibook.yonsei.ac.kr/Viewer/{bookId}

현재 디렉토리에 {책제목}.pdf 파일이 생성됩니다.

#!/usr/bin/env python3
"""연세대 ibook 뷰어에서 책을 PDF로 다운로드합니다."""
import sys
import json
import re
import ssl
import urllib.request
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
import img2pdf
def fetch(url):
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
with urllib.request.urlopen(url, context=ctx) as resp:
return resp.read()
def fetch_to_file(url, path):
path.write_bytes(fetch(url))
def main():
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <ibook-url>")
print(f"Example: {sys.argv[0]} https://ibook.yonsei.ac.kr/Viewer/GEFQ24RMWHC7")
sys.exit(1)
url = sys.argv[1]
bookcode = url.rstrip("/").split("/")[-1]
base = "https://ibook.yonsei.ac.kr"
# 책 제목
html = fetch(f"{base}/Viewer/{bookcode}").decode()
match = re.search(r"<title>(.+?)</title>", html)
title = match.group(1) if match else bookcode
print(f"Title: {title}")
# 페이지 정보
book_json = json.loads(fetch(f"{base}/Viewer/getBookXML/{bookcode}"))
page_count = len(book_json)
print(f"Pages: {page_count}")
# 최고 해상도 이미지 URL 목록
pages = []
for i, page in enumerate(book_json):
src = "https:" + page["src"].replace("scale1", "scale3")
pages.append((src, i))
# 다운로드
pages_dir = Path("pages")
pages_dir.mkdir(exist_ok=True)
paths = [pages_dir / f"{i:03d}.jpg" for i in range(page_count)]
print(f"Downloading {page_count} pages...")
with ThreadPoolExecutor(max_workers=10) as pool:
futures = [pool.submit(fetch_to_file, src, paths[i]) for src, i in pages]
for f in futures:
f.result()
# PDF 생성 (JPEG 원본을 그대로 삽입)
print("Creating PDF...")
output = Path(f"{title}.pdf")
with open(output, "wb") as f:
f.write(img2pdf.convert([str(p) for p in paths]))
print(f"Done: {output} ({output.stat().st_size / 1024 / 1024:.1f}MB)")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment