| name | ktx-booking |
| description | Search, reserve, inspect, and cancel KTX or Korail tickets in Korea with the korail2 + pycryptodome Python packages. Use when the user asks for KTX seats, Korail bookings, train changes, reservation status, remaining seat numbers, car-by-car seats, or power-outlet/good-seat tips. |
| license | MIT |
| metadata | {"category":"travel","locale":"ko-KR","phase":"v1"} |
KTX Booking
What this skill does
korail2 ์์ scripts/ktx_booking.py helper ๋ฅผ ์น์ด KTX/Korail ์กฐํ, ํธ์ฐจ๋ณ ์ข์๋ฒํธ ํ์ธ, ์์ฝ, ์์ฝ ํ์ธ, ์ทจ์๋ฅผ ์ฒ๋ฆฌํ๋ค.
์ต๊ทผ Korail ์ฑ์ Dynapath anti-bot ์ฒดํฌ ๋๋ฌธ์ ์๋ณธ korail2 0.4.0 ์์ ๋ง์ผ๋ก๋ MACRO ERROR ๊ฐ ๋ ์ ์๋ค. ์ด ์คํฌ์ helper ๊ฐ x-dynapath-m-token, Sid, ์ต์ app version(250601002)์ ๋ถ์ฌ ์ค์ ์๋งค ํ๋ฆ์ ๋ณต๊ตฌํ๋ ๊ฒ์ ์ ์ ๋ก ํ๋ค.
When to use
- "์์ธ์์ ๋ถ์ฐ ๊ฐ๋ KTX ์ฐพ์์ค"
- "์ฝ๋ ์ผ ์์ฝ ํ์ธํด์ค"
- "KTX ์ทจ์ํด์ค"
- "์ค์ 9์ ์ดํ KTX ์ค ์ ์ผ ๋น ๋ฅธ ๊ฑฐ ์ก์์ค"
- "KTX ๋จ์ ์ข์ ๋ฒํธ ํ์ธํด์ค"
- "์ด ์ด์ฐจ ์ฝ์ผํธ ์๋ ๊ฟํ ์ข์๋ถํฐ ๋ณด์ฌ์ค"
- "KTX 5ํธ์ฐจ ๋จ์ ์๋ฆฌ๋ง ๋ด์ค"
- "์์ฝํ๊ธฐ ์ ์ ํธ์ฐจ๋ณ ์ข์ ํ์ธํด์ค"
- "N์นด๋๋ก ํ ์ธ ์ด์ฐจ ์ฐพ์์ค"
- "๋ด N์นด๋ ๋ชฉ๋ก ๋ณด์ฌ์ค"
- "N์นด๋ ํ ์ธ ์ ์ฉํด์ ์์ฝํด์ค"
When not to use
- SRT ์๋งค์ธ ๊ฒฝ์ฐ
- ์ค๊ฒฐ์ ํ์ ๊น์ง ์๋ํํด์ผ ํ๋ ๊ฒฝ์ฐ
- credential ์ ํ๋ฌธ์ผ๋ก ๋ฃ์ผ๋ ค๋ ๊ฒฝ์ฐ
Prerequisites
- Python 3.10+
python3 -m pip install korail2-ncard pycryptodome
Required environment variables
KSKILL_KTX_ID
KSKILL_KTX_PASSWORD
Credential resolution order
- ์ด๋ฏธ ํ๊ฒฝ๋ณ์์ ์์ผ๋ฉด ๊ทธ๋๋ก ์ฌ์ฉํ๋ค.
- ์์ด์ ํธ๊ฐ ์์ฒด secret vault(1Password CLI, Bitwarden CLI, macOS Keychain ๋ฑ)๋ฅผ ์ฌ์ฉ ์ค์ด๋ฉด ๊ฑฐ๊ธฐ์ ๊บผ๋ด ํ๊ฒฝ๋ณ์๋ก ์ฃผ์
ํด๋ ๋๋ค.
~/.config/k-skill/secrets.env (๊ธฐ๋ณธ fallback) โ plain dotenv ํ์ผ, ํผ๋ฏธ์
0600.
- ์๋ฌด๊ฒ๋ ์์ผ๋ฉด ์ ์ ์๊ฒ ๋ฌผ์ด์ 2 ๋๋ 3์ ์ ์ฅํ๋ค.
๊ธฐ๋ณธ ๊ฒฝ๋ก์ ์ ์ฅํ๋ ๊ฒ์ fallback์ผ ๋ฟ, ๊ฐ์ ๊ฐ ์๋๋ค.
Inputs
- ์ถ๋ฐ์ญ
- ๋์ฐฉ์ญ
- ๋ ์ง:
YYYYMMDD
- ํฌ๋ง ์์ ์๊ฐ:
HHMMSS
- ์ธ์ ์์ ์น๊ฐ ์ ํ
- ์ข์ ์ ํธ
- ์ข์ ์์ธ ์กฐ๊ฑด: ๊ฐ์ค ๋ฑ๊ธ, ํธ์ฐจ ๋ฒํธ, ๋จ์ ์ข์๋ง ๋ณด๊ธฐ, ์ฝ์ผํธ ๊ฟํ ์ข์ ์ฐ์
- ์กฐํ ๊ฒฐ๊ณผ์์ ๋ณต์ฌํ
train_id
Workflow
0. Install the package globally when missing
python3 -c 'import korail2, Crypto' ๊ฐ ์คํจํ๋ฉด ๋ค๋ฅธ ๊ตฌํ์ผ๋ก ์ฐํํ์ง ๋ง๊ณ ์ ์ญ Python ํจํค์ง ์ค์น๋ฅผ ๋จผ์ ์๋ํ๋ค.
python3 -m pip install korail2-ncard pycryptodome
1. Ensure credentials are available
KSKILL_KTX_ID, KSKILL_KTX_PASSWORD ํ๊ฒฝ๋ณ์๊ฐ ์ค์ ๋์ด ์๋์ง ํ์ธํ๋ค. ์์ผ๋ฉด ์ credential resolution order์ ๋ฐ๋ผ ํ๋ณดํ๋ค.
์ํฌ๋ฆฟ์ด ์๋ค๋ ์ด์ ๋ก ์น์ฌ์ดํธ๋ฅผ ์ง์ ๊ธ๊ฑฐ๋ ๋ค๋ฅธ ๋น๊ณต์ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ง ์๋๋ค.
2. Search first via the helper
ํญ์ helper ๋ฅผ ํตํด ์กฐํํ๋ค.
python3 scripts/ktx_booking.py search ์์ธ ๋ถ์ฐ 20260328 090000 --limit 5
๊ธฐ๋ณธ --train-type ์ ktx ๋ค. ITX-์ฒญ์ถ(์: ๋จ์ถ์ฒโ์ฉ์ฐ)ยทITX-์๋ง์ยท๋ฌด๊ถํํธ์ฒ๋ผ KTX ์ธ ๋
ธ์ ์ ์ก์ผ๋ ค๋ฉด --train-type ์ผ๋ก ์ง์ ํ๋ค.
python3 scripts/ktx_booking.py search ๋จ์ถ์ฒ ์ฉ์ฐ 20260503 150000 --train-type itx-cheongchun
์ ํ์ง: ktx, itx-saemaeul, mugunghwa, nuriro, tonggeun, itx-cheongchun, airport, all.
์์ฝ ๋จ๊ณ(reserve)์์๋ ๊ฐ์ --train-type ๊ฐ์ ๊ทธ๋๋ก ๋๊ฒจ์ผ stable train_id ๋งค์นญ์ด ๊นจ์ง์ง ์๋๋ค.
์ข์์ด ์๋ ์ด์ฐจ๋ ํ๋ณด์ ํฌํจํ๋ ค๋ฉด --include-no-seats, ์์ฝ ๋๊ธฐ ๊ฐ๋ฅํ ์ด์ฐจ๋ ๊ฐ์ด ๋ณด๊ณ ์ถ์ผ๋ฉด --include-waiting-list ๋ฅผ ๋ถ์ธ๋ค.
3. Present the shortlist
์๋งค ์ ์ ํญ์ ์๋๋ฅผ ํ์ธํ๋ค.
index
train_id
- ์ถ๋ฐ/๋์ฐฉ ์๊ฐ
- ์ด์ฐจ ์ข
๋ฅ (
train_type)
- ์ผ๋ฐ์ค/ํน์ค ๊ฐ๋ฅ ์ฌ๋ถ
- ์์ฝ ๋๊ธฐ ๊ฐ๋ฅ ์ฌ๋ถ
4. Inspect detailed seats when the user asks for good seats
search ์ ์ข์ ๊ฐ๋ฅ ์ฌ๋ถ๋ ์ด์ฐจ ๋จ์ ํ๋๊ทธ๋ค. ์ฌ์ฉ์๊ฐ "๋จ์ ์ข์ ๋ฒํธ", "ํธ์ฐจ๋ณ ์ข์", "์ฝ์ผํธ", "๊ฟํ ์ข์", "์ฐฝ์ธก/์๋ฐฉํฅ ์๋ฆฌ", "์์ฝ ์ ์ ์๋ฆฌ ํ์ธ"์ฒ๋ผ ๊ตฌ์ฒด์ ์ธ ์ข์์ ๋ฌผ์ผ๋ฉด ์์ฝ ์ ์ seats ๋ฅผ ํธ์ถํ๋ค.
๊ธฐ๋ณธ ์์ธ ์ข์ ์กฐํ:
python3 scripts/ktx_booking.py seats ์์ธ ๋ถ์ฐ 20260328 090000 --train-id <train_id>
์ผ๋ฐ์ค/ํน์ค์ --room ์ผ๋ก ๋๋๋ค.
python3 scripts/ktx_booking.py seats ์์ธ ๋ถ์ฐ 20260328 090000 --train-id <train_id> --room special
๋จ์ ์ข์๋ฒํธ๋ง ๋ณด๊ณ ์ถ์ผ๋ฉด --available-only ๋ฅผ ์ด๋ค.
python3 scripts/ktx_booking.py seats ์์ธ ๋ถ์ฐ 20260328 090000 --train-id <train_id> --available-only
ํน์ ํธ์ฐจ๋ฅผ ์ง์ ํ์ง ์์ผ๋ฉด seats ๋ ์น๊ฐ์ฅ ์ด๋ ๊ฑฐ๋ฆฌ๊ฐ ์งง์ ๊ฐ์ด๋ฐ ํธ์ฐจ๋ถํฐ ํ์ํ๋ค. ๊ฐ ํธ์ฐจ ์์ ์ข์์ ์ฝ์ผํธ ํํธ๊ฐ ์๋ ์ข์(direct, adjacent)์ ๋จผ์ , ๊ฐ์ ์กฐ๊ฑด์์๋ ์๋ฐฉํฅ ์ข์์ ๋จผ์ ๋ณด์ฌ์ค๋ค.
ํน์ ํธ์ฐจ๋ง ํ์ธํ๋ ค๋ฉด --car-no ๋ฅผ ์ด๋ค.
python3 scripts/ktx_booking.py seats ์์ธ ๋ถ์ฐ 20260328 090000 --train-id <train_id> --car-no 5 --available-only
์ฝ์ผํธ ๊ฟํ ์๋ฆฌ๋ถํฐ ํ์ธํ๋ ค๋ฉด --power-only ๋ฅผ ๋ถ์ธ๋ค. ์๋ต์ power_outlet ์ direct, adjacent, none ์ค ํ๋๋ค.
python3 scripts/ktx_booking.py seats ์์ธ ๋ถ์ฐ 20260328 090000 --train-id <train_id> --available-only --power-only
seats ๋ search ์ ๊ฐ์ --train-type ์ ๋๊ฒจ์ผ ํ๋ค. ITX-์ฒญ์ถ ๋ฑ KTX ์ธ ์ด์ฐจ๋ฅผ ์กฐํํ๋ค๋ฉด ์์ธ ์ข์ ์กฐํ์๋ ๊ฐ์ ๊ฐ์ ์ฌ์ฉํ๋ค.
python3 scripts/ktx_booking.py seats ๋จ์ถ์ฒ ์ฉ์ฐ 20260503 150000 \
--train-id <train_id> \
--train-type itx-cheongchun \
--available-only
์์ธ ์ข์ ์๋ต์ ๋ณด์ฌ์ค ๋๋ ์ฌ์ฉ์ ์๋์ ๋ง์ถฐ ์๋๋ฅผ ์ฐ์ ์์ฝํ๋ค.
- ํธ์ฐจ๋ณ
remaining_seats, available_seat_count
- ๋จ์ ์ข์ ๋ฒํธ (
available_seats)
- ์ข์๋ณ
direction, position, seat_type
- ์ฝ์ผํธ ํํธ (
power_outlet)
- ๋ฌธ ๊ทผ์ฒ ์ฌ๋ถ (
near_door)
์ด ๊ธฐ๋ฅ์ ์ข์์ ์ ํ/์ ์ ํ์ง ์๋๋ค. ์ค์ ์์ฝ์ ๋ค์ ๋จ๊ณ์ reserve ๋ก๋ง ์งํํ๋ค.
5. Reserve only after the target train is unambiguous
์กฐํ ๊ฒฐ๊ณผ์ train_id ๋ฅผ ๊ณ ๋ฅธ ๋ค์๋ง ์์ฝํ๋ค. ์ด ๊ฐ์ helper ๊ฐ ์ด์ฐจ ๋ฒํธ/์ดํ์ผ/์๊ฐ/์ญ ์ฝ๋๋ฅผ ๋ฌถ์ด ๋ง๋ stable selector ์ด๋ฏ๋ก, ์ฌ์กฐํ ์ ๊ฐ์ ์ด์ฐจ๊ฐ ์์ง ์์ผ๋ฉด ๊ทธ๋๋ก ์ก๊ณ ์์ผ๋ฉด ์คํจํ๋ค.
python3 scripts/ktx_booking.py reserve ์์ธ ๋ถ์ฐ 20260328 090000 --train-id <train_id> --seat-option general-first
ITX ๋ฑ KTX ์ธ ๋
ธ์ ์ search ๋จ๊ณ์์ ๊ณจ๋๋ค๋ฉด reserve ์๋ ๋๊ฐ์ด --train-type ์ ๋๊ธด๋ค.
python3 scripts/ktx_booking.py reserve ๋จ์ถ์ฒ ์ฉ์ฐ 20260503 150000 --train-id <train_id> --train-type itx-cheongchun --seat-option general-first
์๋ต์๋ ์์ฝ๋ฒํธ, ์ด์, ๊ตฌ์
๊ธฐํ์ด ํฌํจ๋๋ค. ๊ฒฐ์ ๋ ์๋ํํ์ง ์๋๋ค.
์ข์์ด ์์ ๋๋ ์กฐํ ๋จ๊ณ์์ --include-waiting-list ๋ฅผ ์ผ๊ณ ์์ฝ ๋จ๊ณ์์ --try-waiting ์ผ๋ก ์์ฝ ๋๊ธฐ๊น์ง ์๋ํ ์ ์๋ค.
5-1. N-card discounted reservation
N์นด๋ ํ ์ธ์ ์ ์ฉํ๋ ค๋ฉด ๋จผ์ ๋ณด์ N์นด๋ ๋ชฉ๋ก์ ์กฐํํด ์นด๋ ๋ฒํธ๋ฅผ ํ์ธํ๋ค.
python3 scripts/ktx_booking.py ncard-list
N์นด๋๋ก ํ ์ธ ์ด์ฐจ๋ฅผ ์กฐํํ๋ค (--ncard-index ๋ ncard-list ๊ฒฐ๊ณผ์ ์๋ฒ). ncard-list ๋ ๋ก๊ทธ/์
ธ ๋
ธ์ถ์ ์ค์ด๊ธฐ ์ํด ์นด๋ ๋ฒํธ๋ฅผ ๋ง์คํนํด ์ถ๋ ฅํ๋ค.
python3 scripts/ktx_booking.py ncard-search ๋์ ์์ธ 20260512 100000 --ncard-index 1 --train-type ktx
์๋ต์ train_id ๋ฅผ ๋ณต์ฌํด reserve ์ ๊ฐ์ --ncard-index ๋ฅผ ๋ถ์ฌ ์์ฝํ๋ค.
python3 scripts/ktx_booking.py reserve ๋์ ์์ธ 20260512 100000 \
--train-id <train_id> \
--ncard-index 1
--ncard-index ๋ฅผ ์ง์ ํ๋ฉด --adults ๋ฑ ์น๊ฐ ์ต์
์ ๋ฌด์๋๊ณ N์นด๋ ์น๊ฐ 1๋ช
์ผ๋ก ์ฒ๋ฆฌ๋๋ค. --ncard-no ์ง์ ์
๋ ฅ๋ ์ง์ํ์ง๋ง ์
ธ ํ์คํ ๋ฆฌ์ ๋จ์ ์ ์์ด ๊ถ์ฅํ์ง ์๋๋ค. ๊ฒฐ์ ๋ ์๋ํํ์ง ์๋๋ค.
N์นด๋ ๊ธฐ๋ฅ์ korail2-ncard ํจํค์ง๊ฐ ํ์ํ๋ค. ์์ผ๋ฉด ํด๋น ์ปค๋งจ๋ ์คํ ์ ์ค์น ์๋ด๊ฐ ์ถ๋ ฅ๋๋ค.
6. Inspect or cancel
์ทจ์๋ ๋์ ์์ฝ์ ๋ค์ ์กฐํํด ์๋ณํ ๋ค์๋ง ์งํํ๋ค.
python3 scripts/ktx_booking.py reservations
python3 scripts/ktx_booking.py cancel <reservation_id>
Done when
- ์กฐํ๋ฉด ์ด์ฐจ ํ๋ณด๊ฐ ์ ๋ฆฌ๋์ด ์๋ค
- ์ข์ ์์ธ ํ์ธ์ด๋ฉด ํธ์ฐจ๋ณ ๋จ์ ์ข์๋ฒํธ์ ํ์ํ ๊ฟํ ์กฐ๊ฑด์ด ์ ๋ฆฌ๋์ด ์๋ค
- ์์ฝ์ด๋ฉด ์์ฝ ๊ฒฐ๊ณผ์ ์ ํ ์๊ฐ์ด ํ์ธ๋์ด ์๋ค
- ์ทจ์๋ฉด ์ด๋ค ์์ฝ์ ์ทจ์ํ๋์ง ๋จ์ ์๋ค
Failure modes
- ๋ก๊ทธ์ธ ์คํจ
- ๋งค์ง
- Korail anti-bot ๊ท์น ๋ณ๊ฒฝ
Notes
scripts/ktx_booking.py ๋ upstream korail2 anti-bot ํ๊ท๋ฅผ ๋ณด์ํ๋ helper ๋ค
korail2 ๋ KTX/Korail ์ ์ฉ ํ๋ฉด์ด๋ผ train type ๊ณผ passenger model ์ด ๋ถ๋ช
ํ๋ค
- ๊ฒฐ์ ์๋ฃ๊น์ง๋ ์๋ํํ์ง ์๋๋ค
- aggressive polling ์ ํผํ๋ค