Sangtacviet Batch Downloader v2 (쌀국수 자체 캡챠 대응)
Sangtacviet Batch Downloader v2
Unified Browser + Python + Auto Captcha
기존
Sangtacviet Batch Downloader를 기반으로 대량 회차 다운로드에 필요한 기능을 대폭 확장한 버전입니다.v2에서는 DrissionPage 기반 브라우저 제어, Google reCAPTCHA 대응, Sangtacviet 자체 CAPTCHA 대응, 소설/회차 제목 캐싱, 기존 파일 자동 스킵, 회차 ID 기반 이어받기, 성공·스킵·실패 내역 관리, 작업별 결과 로그 등을 추가했습니다.
특히 수백~수천 화 규모의 장시간 다운로드를 염두에 두고, 이미 받아둔 파일을 다시 다운로드하지 않고 이어서 작업할 수 있도록 캐시와 완료 내역 관리 기능을 강화했습니다.
코드 작성에는 Gemini(다른 AI들과 다르게 크롤링용 코드도 작성해줌), GPT(직접 작성은 안해주나, 코드 검토를 도와줌)의 도움을 받았습니다.
✨ v1 → v2 주요 변경점
1. 브라우저 제어 엔진 변경
v1은 **Playwright + playwright-stealth**를 기반으로 원격 디버깅 중인 Chrome을 제어하는 비교적 간단한 구조였습니다. Playwright로 Chrome의 페이지를 직접 제어하고, Stealth 모드를 적용한 뒤 페이지 이동과 본문 추출을 수행하는 방식입니다.
v2에서는 브라우저 제어 계층을 DrissionPage의 ChromiumPage / ChromiumOptions 기반으로 전환했습니다.
단순 페이지 이동뿐 아니라 iframe, 동적 콘텐츠, CAPTCHA 상태, 브라우저 팝업 등의 상태를 보다 세밀하게 확인하고 처리할 수 있도록 전체 다운로드 흐름을 확장했습니다.
🛡️ CAPTCHA 대응 기능 강화
v2의 가장 큰 변경점 중 하나입니다.
기존 버전은 reCAPTCHA를 감지한 뒤 기본적인 클릭 및 수동 처리에 의존하는 구조였습니다.
v2에서는 CAPTCHA 처리를 별도의 RecaptchaSolver 클래스로 분리하고, Google reCAPTCHA와 Sangtacviet 자체 CAPTCHA를 구분하여 처리합니다.
Google reCAPTCHA 대응
v2의 RecaptchaSolver에는 다음과 같은 처리 흐름이 포함되어 있습니다.
reCAPTCHA 체크박스 감지
체크박스 상태 확인
추가 챌린지 발생 여부 확인
오디오 챌린지 진입
오디오 파일 다운로드
MP3 → WAV 변환
음성 인식 처리
인식 결과 입력 및 확인
처리 성공 여부 재확인
자동 처리 실패 시 예외 처리
코드에는 실제 오디오 챌린지를 처리하기 위한 pydub 및 SpeechRecognition 연동이 포함되어 있습니다.
Sangtacviet 자체 CAPTCHA 대응
Google reCAPTCHA와 별개로 사이트 자체 CAPTCHA도 별도로 감지합니다.
iframe 정보를 확인하여 reCAPTCHA 관련 프레임을 찾고, 사이트 특유의 CAPTCHA 상태를 확인한 뒤 별도의 처리 흐름으로 전환합니다.
다운로드 루프에서도 사이트 자체 CAPTCHA와 Google reCAPTCHA 챌린지를 각각 확인하도록 구성되어 있습니다.
자동 처리로 해결되지 않는 상황에서는 사용자가 브라우저에서 직접 처리할 수 있도록 대기한 뒤 다운로드를 계속할 수 있습니다.
주의: CAPTCHA 처리 여부와 방식은 사이트 상태 및 외부 서비스의 변경에 따라 달라질 수 있습니다.
(v1과 마찬가지로 자동 CAPTCHA 처리 실패 → 비프음 → 사용자가 처리 → 자동 재개)
📚 소설 제목 및 전체 목차 캐싱
v2에서는 소설을 처음 처리할 때 메인 페이지의 정보를 한 번 가져와 소설 제목과 회차 제목을 전체적으로 캐싱합니다.
브라우저 내부 JavaScript를 이용하여 제목과 회차 링크를 일괄 수집하고 다음과 같은 구조로 저장합니다.
novel_cache.json
소설 URL
├─ 소설 제목
└─ 회차 ID
└─ 회차 제목
이후 회차 처리에서는 이미 확보된 목차 정보를 우선 사용하기 때문에 회차별 제목을 매번 새로 찾아야 하는 부담을 줄일 수 있으며, v1과 다르게 중국어로 된 원제로 소설을 저장합니다. 회차별 소제목은 해당 사이트에 중국어 원제가 없으므로, 베트남어로 저장됩니다.
ex) 东京:从漫画助手到ACGN大神_Thứ 200 chương Đạo khác biệt.txt
또한 목차 캐시는 디스크에 저장되므로 프로그램을 종료했다가 다시 실행해도 기존 캐시를 사용할 수 있습니다.
🚀 기존 파일 자동 스킵 및 이어받기
v1에는 본격적인 이어받기 체계가 없어, 기존에 받아둔 파일을 다시 다운로드할 가능성이 있었습니다.
v2에서는 회차 ID 기반 완료 Manifest를 도입했습니다.
completed_chapters.json
이 파일에는 소설과 회차를 식별할 수 있는 정보와 실제 저장 파일 정보가 기록됩니다.
스킵 처리 순서
v2의 이어받기 기능은 다음 순서로 동작합니다.
회차 URL
↓
소설 URL + Chapter ID 생성
↓
완료 Manifest 확인
↓
이미 완료됨?
├─ YES → 실제 파일 존재 확인 → 브라우저 접속 없이 스킵
└─ NO
↓
목차 캐시를 이용해 기존 파일 확인
↓
파일이 이미 존재?
├─ YES → 브라우저 접속 없이 스킵
└─ NO → 정상 다운로드
Manifest에 없는 기존 파일도 실제 파일 시스템에서 찾아내며, 발견한 파일은 이후 실행을 위해 Manifest에 자동으로 등록합니다.
따라서 이전 버전에서 이미 받아둔 파일을 가지고 v2를 시작하는 경우에도 가능한 회차를 다시 다운로드하지 않고 이어받을 수 있습니다.
🔑 소설별 Chapter ID 관리
v2에서는 입력 목록의 순번(idx)과 실제 회차 식별자를 구분합니다.
예를 들어:
입력 1번 → Chapter ID 123456
입력 2번 → Chapter ID 123457
입력 3번 → Chapter ID 123458
처럼 관리합니다.
또한 여러 소설에서 동일한 Chapter ID가 존재할 가능성을 고려하여:
base_url + Chapter ID
를 조합한 Manifest 키를 사용합니다.
따라서:
A소설 / ID 207
B소설 / ID 207
은 서로 다른 항목으로 관리됩니다.
A소설을 다운로드하다가 B소설을 처리한 뒤 다시 A소설로 돌아가더라도 A소설의 캐시와 완료 내역은 그대로 유지됩니다.
🧠 회차 제목 복구 및 캐시 우선 처리
본문 페이지에서 회차 제목을 항상 안정적으로 얻을 수 있는 것은 아니기 때문에 v2에서는 여러 단계의 복구 방식을 사용합니다.
처리 우선순위는 다음과 같습니다.
1. 목차 캐시에 저장된 회차 제목
2. 페이지의 JavaScript 변수
3. 회차 제목 DOM 요소
4. 페이지 HTML의 회차 제목
5. 최종 기본값
목차 캐시에서 회차 제목을 찾지 못하는 경우에만 페이지 내부 정보를 추가로 확인하도록 구성되어 있습니다.
또한 <i> 태그의 t, zw 속성 등 사이트 특유의 원문 데이터도 처리하도록 기존 본문 추출 로직을 유지했습니다.
🔄 동적 본문 로딩 및 재시도 개선
사이트의 본문이 처음 페이지 로드 시 바로 완성되지 않는 경우를 고려하여 v2에서는 본문 영역의 표시 여부와 로딩 문구를 반복적으로 확인합니다.
또한 본문 추출 시:
첫 시도
→ 이미 확보한 안정화 HTML 사용
실패
↓
스크롤 및 대기
↓
최신 HTML 다시 확보
↓
재추출
방식으로 재시도합니다.
따라서 정상적인 경우에는 불필요한 페이지 재조회가 줄어들고, 동적 로딩 문제가 발생한 경우에는 최신 상태를 기준으로 다시 시도합니다.
⏭️ 성공 / 스킵 / 실패 항목 분리
v2에서는 결과를 단순한 숫자 목록이 아니라 구조화된 데이터로 관리합니다.
성공
실제로 새로 다운로드하여 저장된 회차입니다.
✅ 성공한 회차
- 입력 순번
- Chapter ID
- 제목
- 파일명
스킵
다음과 같은 경우입니다.
⏭️ 스킵
- 이미 다운로드된 기존 파일
- VIP / 로그인 필요 항목 등 의도적으로 건너뛴 항목
실패
실제 처리 과정에서 문제가 발생한 항목입니다.
❌ 실패
- 페이지 접속 오류
- 본문 로딩 실패
- 텍스트 추출 실패
v2에서는 이 세 범주를 서로 구분하여 관리합니다.
이 덕분에 많은 회차를 처리한 후에도 어떤 항목을 다시 확인해야 하는지 쉽게 알 수 있습니다.
💾 캐시 및 완료 내역의 안정성
v2는 다음 두 파일을 사용합니다.
novel_cache.json
└─ 소설 제목 / 목차 정보
completed_chapters.json
└─ 다운로드 완료 회차 / 저장 파일 정보
두 파일 모두 임시 파일에 먼저 기록한 뒤 기존 파일과 교체하는 방식으로 저장합니다.
캐시를 읽을 수 없을 경우 기존 파일을 .bad 파일로 보존한 뒤 새 캐시로 시작하도록 처리되어 있습니다.
따라서 장시간 작업 중 예상치 못한 종료가 발생하더라도 기존 캐시를 바로 잃을 가능성을 줄였습니다.
📝 작업별 결과 로그
v1의 단일 결과 로그 방식에서 벗어나, v2에서는 작업 시작 시간을 포함한 개별 로그 파일을 생성합니다.
예:
download_report_success_2026-08-12_20-15-30.txt
download_report_success_2026-08-12_22-41-07.txt
download_report_interrupt_2026-08-12_23-10-52.txt
따라서 여러 번 작업을 실행해도 이전 작업의 로그가 덮어써지지 않습니다.
로그에는 다음 정보가 포함됩니다.
작업 시작 시간
작업 완료 시간
총 소요 시간
전체 회차 수
성공 회차
스킵 회차
실패 회차
각 항목의 입력 순번
Chapter ID
제목 / 실패 사유
파일명
🛑 중단 시 별도 로그 생성
작업 도중 프로그램이 중단된 경우에도 현재까지의 상태를 별도의 중단 로그에 저장합니다.
예:
download_report_interrupt_2026-08-12_23-10-52.txt
여기에는 현재까지 성공·스킵·실패한 항목이 기록되므로, 이후 작업을 재개하거나 문제 회차를 확인하기 쉽습니다.
🆚 v1과 v2 비교
항목 | v1 | v2 |
|---|---|---|
브라우저 엔진 | Playwright | DrissionPage |
Chrome 원격 제어 | ✅ | ✅ |
순차 Batch 다운로드 | ✅ | ✅ |
소설 제목 캐시 | ❌ | ✅ |
전체 목차 캐시 | ❌ | ✅ |
디스크 캐시 | ❌ | ✅ |
완료 Manifest | ❌ | ✅ |
기존 파일 자동 스킵 | ❌ | ✅ |
기존 파일 → Manifest 자동 등록 | ❌ | ✅ |
소설별 Chapter ID 관리 | 제한적 | ✅ |
A → B → A 캐시 유지 | 제한적 | ✅ |
성공 / 스킵 / 실패 분리 | 기본적 | ✅ |
VIP/로그인 필요 항목 구분(쌀국수 사이트 미업로드 부분) | ❌ | ✅ |
Google reCAPTCHA 대응 | 기본 감지/수동 대응 | 별도 처리 모듈 추가 |
오디오 챌린지 처리 | ❌ | ✅ |
Sangtacviet 자체 CAPTCHA 대응 | 제한적 | ✅ |
동적 본문 재시도 | 기본적 | 향상 |
캐시 손상 대응 | ❌ | ✅ |
작업별 결과 로그 | 단일 파일 | 타임스탬프별 파일 |
중단 로그 | 제한적 | ✅ |
장시간 이어받기 | 제한적 | ✅ |
⚙️ 시스템 요구사항
필수 환경
OS: Windows 10 / 11
Browser: Google Chrome
Python: Python 3.8 이상
Chrome 원격 디버깅: 포트
9222
Python 패키지
pip install flask flask-cors beautifulsoup4 DrissionPage pydub SpeechRecognition
추가 사항
pydub의 오디오 처리 기능을 사용하므로 시스템 환경에 따라 오디오 디코딩에 필요한 외부 도구를 별도로 준비해야 할 수 있습니다.
winsound를 사용하는 알림 기능이 포함되어 있기 때문에 현재 버전은 Windows 환경을 기준으로 합니다.
🛠️ 설치 방법
1. Python 설치
Python 3.8 이상을 설치합니다.
설치 후 다음 명령으로 확인할 수 있습니다.
python --version
2. 필수 패키지 설치
pip install flask flask-cors beautifulsoup4 DrissionPage pydub SpeechRecognition
3. FFmpeg 설치
FFmpeg를 별도로 설치해야 합니다.
FFmpeg는 Google ReCAPTCHA 오디오 처리 과정에서 MP3 등의 오디오 파일을 WAV로 변환할 때 사용됩니다.
winget install Gyan.FFmpeg4. Tampermonkey 스크립트 설치
크롬에 Tampermonkey 확장프로그램을 설치합니다.
Tampermonkey 대시보드에서
새 스크립트 만들기를 클릭합니다.제공된
// ==UserScript==로 시작하는 자바스크립트 코드를 붙여넣고 저장(Ctrl+S)합니다.
( chrome://extensions/에서 개발자 모드 및 Tampermonkey 세부정보에서 사용자 스크립트 허용 필수)
※ tampermonkey 스크립트 Sangtacviet Batch Downloader (Unified Browser + Python).js는, v1 버전과 완전히 동일함.
5. Chrome 원격 디버깅 모드 설정
실행 중인 Chrome을 완전히 종료한 뒤 다음과 같이 실행합니다.
chrome.exe --remote-debugging-port=9222
Chrome 바로가기의 대상(Target) 끝에 다음을 추가해두면 편리합니다.
--remote-debugging-port=9222
예:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222
💻 사용 방법
1. Chrome 실행
원격 디버깅 모드로 Chrome을 실행합니다.
2. Python 서버 실행
python "Sangtacviet_Batch_Downloader_v2.py"
정상 실행 시 다음과 같은 메시지가 표시됩니다.
✅ 서버 준비 완료! 포트 15000
3. 다운로드 작업 요청 (Tampermonkey 스크립트 활용)
디버깅 모드로 켜진 크롬에서 쌀국수 사이트의 다운로드 받을 소설 목차 페이지에 접속합니다.
상단에 추가된 컨트롤 바에서 다운로드할 화를 선택(
사이 선택등 활용)합니다.🟡 [🐍 파이썬 봇으로 전송] 버튼을 클릭합니다.
📁 저장 구조
프로그램이 실행되는 폴더를 기준으로 다음과 같은 구조가 만들어집니다.
Sangtacviet_Batch_Downloader_v2.py
novel_cache.json
completed_chapters.json
└─ 소설 제목/
├─ 소설 제목_회차 제목 1.txt
├─ 소설 제목_회차 제목 2.txt
├─ 소설 제목_회차 제목 3.txt
├─ download_report_success_2026-08-12_20-15-30.txt
└─ ...
캐시와 완료 내역은 프로그램 폴더에 별도로 저장됩니다.
🔁 여러 소설을 연속으로 처리하는 경우
v2는 소설별로 캐시와 완료 내역을 유지합니다.
예:
A소설
↓
A|123
A|124
A|125
B소설
↓
B|123
B|124
다시 A소설
↓
A|123 → 이미 완료 → 스킵
A|124 → 이미 완료 → 스킵
A|125 → 이미 완료 → 스킵
소설이 변경되어도 이전 소설의 캐시가 삭제되지 않으며, 소설 URL과 Chapter ID를 조합하여 각각 독립적으로 관리합니다.
🚨 주의사항
다운로드 작업 중 연결된 Chrome 창이나 현재 작업 탭을 임의로 닫거나 변경하지 않는 것을 권장합니다.
장시간 작업에서는 사이트 응답 속도와 외부 서비스 상태에 따라 전체 처리 시간이 크게 달라질 수 있습니다.
CAPTCHA가 발생하는 경우 자동 처리 여부와 처리 시간은 상황에 따라 달라질 수 있습니다.
자동 처리할 수 없는 인증이 발생하면 사용자의 수동 처리가 필요할 수 있습니다.
novel_cache.json과completed_chapters.json은 이어받기 및 중복 다운로드 방지에 사용되므로 정상적인 작업 중에는 삭제하지 않는 것이 좋습니다.동일한 소설을 다시 다운로드하더라도 기존 파일과 완료 내역이 있으면 해당 회차는 가능한 한 재다운로드하지 않고 스킵합니다.
Google Recaptcha 해제 기능은 작동하지 않을 수 있습니다.
💡 1000화처럼 대량 작업할 때
v2는 한 번에 많은 회차를 처리하는 것을 염두에 두고 설계되었습니다.
특히 다음과 같은 상황에서 장점이 있습니다.
1000화 다운로드 시작
↓
400화까지 성공
↓
프로그램 중단
↓
다음 실행
↓
기존 1~400화 확인
↓
이미 받은 회차 스킵
↓
401화 이후부터 계속 진행
또한 중간에 일부 회차가 VIP 로그인 필요(아직 쌀국수 사이트에 안 올라온 부분), 로딩 실패 등의 이유로 처리되지 않더라도 성공·스킵·실패 목록에서 해당 항목을 구분하여 확인할 수 있습니다.
📌 v2 요약
Sangtacviet Batch Downloader v2는 단순히 여러 URL을 순서대로 다운로드하는 데서 끝나는 프로그램이 아니라,
브라우저 제어 + CAPTCHA 대응 + 목차 캐싱 + 기존 파일 스킵 + 회차 ID 기반 이어받기 + 결과 관리
를 하나로 묶은 대량 회차 다운로드용 확장 버전입니다.
v1이 기본적인 다운로드 기능에 초점을 맞췄다면, v2는 장시간·대량 작업을 반복해도 불필요한 재다운로드를 줄이고 작업 상태를 잃지 않도록 하는 것에 초점을 맞췄습니다.
1줄 요약: 쌀국수 캡챠에 지는 거에요? 아니 이겨
그리고, 기본적으로 페이지 로딩 완료 후의 대기시간은 4~8초로 되어있는데, 수정이 필요하면 아래 부분에서 min_wait = 4.0, max_wait = 8.0을 원하는 숫자로 변경하면 됩니다.
if idx < len(urls):
min_wait = 4.0
max_wait = 8.0
wait_time = random.uniform(min_wait, max_wait)
print(f" 👀 봇 탐지 방지: {wait_time:.1f}초간 사람처럼 스크롤하며 대기합니다...")
end_time = time.time() + wait_time
while time.time() < end_time:
s/ainovel
• 7,083 subscribers- 1. ※번역 요청 규칙※
본문에 원문 또는 후기 혹은 원문과 후기 둘 다 포함 필수. ex. [후기] 검도지로 1~2340 완; 또는 [원문/후기] 검도지로 1~2340 완 그 외 번역 요청은 이 글이 아닌 번역 요청 공지글에 댓글로 작성해주세요. 타 사이트의 자료 요청 금지. ※요청 규칙 미숙지시 7일 차단※
- 2. ※복구 요청 규칙※
원글 링크를 붙여주세요. 복구 자료는 복구 요청글의 링크를 첨부해주세요. 복구 요청은 공유할때까지 도배하지말고 기다려주세요. ※요청 규칙 미숙지시 7일 차단※
- 3. 욕설 및 비속어 금지
욕설, 비하, 혐오, 성적인 발언, 정치적 조롱 등은 일절 금지합니다. 상대를 직접적으로 공격하거나 조롱하는 행위는 즉시 제재 대상이 됩니다.
- 4. 분쟁 자제
의견 충돌이 발생하더라도 인신공격 없이 논리적인 대화 로 해결하도록 합니다. 지속적으로 분쟁을 유발하는 행위는 경고 또는 차단 조치의 대상이 됩니다.
- 5. 게시글 및 댓글 작성 기준
허위정보, 루머, 도배, 낚시성 게시물 은 삭제될 수 있습니다. 컨텐츠 관련 비판은 허용하되, 사람을 향한 비난은 허용되지 않습니다.
- 6. 공유 링크는 base64로 암호화 필수 (즉 본문 링크는 base64로 복호화 필요)
※연재처의 링크는 암호화 대상에서 제외합니다※
- 7. 닉네임 언급 및 친목 금지.
Deleted comment.
Deleted comment.
Deleted comment.