빠른 시작¶
전부 읽기입니다. 무엇도 만들지 않고 돈이 움직이지 않습니다.
from srt_mobile_api import PassengerCounts, SrtClient, TrainSearchQuery
client = SrtClient()
client.login("you@example.com", "password") # 이메일·휴대폰번호·회원번호 중 하나
query = TrainSearchQuery(
departure_station_code="0551", # 수서
arrival_station_code="0015", # 동대구
departure_date="20260809", # YYYYMMDD
departure_time="060000", # HHMMSS — 이 시각부터 검색
passengers=PassengerCounts(adult=1),
)
for train in client.search_trains(query).trains:
print(train.train_no, train.departure_time,
train.general_seat_availability_name) # 예: "예약가능"
for reservation in client.get_reservations().reservations: # 없으면 빈 리스트
print(reservation.pnr_no)
client.close()
역 코드는 srt_mobile_api.stations 에 있습니다. SrtClient() 는 설정 없이 동작합니다.
SrtConfig 는 타임아웃·User-Agent·기기키용이며 app.srail.or.kr 와 NetFunnel
원점(nf.letskorail.com) 외의 주소는 거부합니다.
기기키 기본값은 ANDROID_ID 모양의 자리채움 값입니다. 실기기 값을 쓰려면
SRT_DEVICE_KEY 로 넘기고, 값은 adb shell settings get secure android_id 로
읽으면 됩니다. 안드로이드 8부터 이 값은 앱 서명키별로 갈리므로 adb shell 이 보는
것과 SRT 앱이 보는 것은 다릅니다 — 여기서 중요한 건 진짜냐가 아니라 실행 간에
안정적이냐입니다.
타입이 좁혀진 파라미터¶
셋은 export 된 Literal 별칭이라 오타가 타입 오류가 됩니다. 응답에서 읽어 온 코드는 좁히지
않고 str 그대로 둡니다.
| 별칭 | 값 |
|---|---|
SrtSeatAttrCode |
"015", "021", "028" |
SrtTrainGroupCode |
"300", "900", "109" |
MutationCategory |
reserve, cancel, payment, refund, coupon |
korail-mobile-api 와 같이 쓸 때
`TrainSearchQuery`, `DiscountCoupon`, `MutationCategory` 는 두 패키지가 각자 export
하는데 호환되지 않습니다. `passengers` 는 여기가 `PassengerCounts`, KORAIL 이 `int`
이고, `departure_time` 기본값도 `"060000"` 대 `"000000"` 으로 다릅니다.
잘못 import 해도 타입 검사는 통과하고 요청만 틀리게 만들어집니다. 둘 다 쓴다면
`srt_mobile_api.TrainSearchQuery` 처럼 패키지를 붙이세요.
무엇을 할 수 있나¶
전부 SrtClient 의 메서드이고, 각 docstring 이 근거(APK 파일·행 번호 또는 실 응답)를 답니다.
읽기 — 동의가 필요 없습니다¶
| 메서드 | 하는 일 |
|---|---|
login / logout / clear_session / close |
앱과 같은 순서의 로그인, 세션 종료, 로컬 상태 폐기, 연결 종료 |
search_trains / search_group_trains / search_transfer_trains / search_public_discount_trains |
직통·단체(10명 이상)·환승·공공할인 조회 |
iter_train_search_pages(query, group=False, max_pages=10) |
조회의 지연 페이지네이션. 커서가 끊기면 멈춥니다 |
get_timetable / get_fare / get_seat_page / get_seat_grid |
정차역, 좌석 등급별 운임(여정 한 다리), 남은 호차, 좌석배치도 |
get_reservations / get_ticket_list / get_discount_coupons / get_public_discounts |
예약 목록(타입이 붙은 유일한 읽기), 승차권 페이지, 보유 쿠폰, 승인받은 공공할인 자격 |
get_typed_notice_list / get_notice_list / get_main / get_station_selector 외 |
공지(파싱본·원본)와 앱이 밟는 페이지·팝업 선택 화면들 |
상태변경 — consent: MutationConsent 가 필요합니다¶
키워드로 넘겨야 하고, 기본 dry_run=True 에서는 MutationPreview 만 돌려줍니다.
아래 안전 모델 절을 먼저 읽어야 합니다.
| 메서드 | 하는 일 |
|---|---|
reserve(train, consent=...) |
개인예약. 미결제 홀드와 PNR. 선택 인자로 standby=True(예약대기 jobId=1102), round_trip=True(왕복 rtnDv=1), designated_seats=(좌석지정 jobId=1103), seat_attr_code= |
reserve_transfer(itinerary, ...) |
환승. 요청 하나에 두 여정 |
cancel(hold_or_pnr, ...) |
미결제 홀드 해제. 맨 PNR 로 취소할 때만 journey_count 를 직접 줍니다 |
pay_with_card(reservation, card, ...) |
신용카드 결제. 동의 외에 카드 종류 주장이 하나 더 필요합니다 |
get_refund_ticket_info(pnr) → refund(ticket_info, ...) |
환불. 앞은 읽기, 뒤가 상태변경입니다 |
register_discount_coupon(number, password, ...) |
쿠폰 등록. 미리보기까지만 됩니다 |
맞지 않는 조합(예약대기를 제공하지 않는 행, 인원과 다른 좌석 수, 코레일 전용역이 낀 왕복)은
전송 전에 ValueError 로 막습니다.