본문 바로가기
프로젝트/SRT&KTX 매진표 예매

SRT&KTX 기차표 매크로 예매 - (2) SRT 로그인

by 매크로메이커 2024. 1. 8.

KTX보다는 SRT 매진이 훨씬 빨리되는 편이다. 따라서 SRT를 먼저 개발한다.

 

기차표를 예매하려면 우선 로그인을 해야한다. 로그인 기능을 구현해보자.

 

Session 받기

srt 예약 홈페이지에 들어가 개발자도구를 켜고 쿠키를 살펴보면 세션키가 있는 것을 볼 수 있다.

로그인에 앞서 세션을 받아오는 기능을 먼저 만들어야 한다.

세션키를 발급받아야 하는 SRT 웹사이트

 

쿠키를 모두 지우고 홈페이지에 다시 접속해서 Network를 살펴보자

 

쿠키가 빈 상태에서 https://etk.srail.kr/main.do 에 접속하면 Response Header에 세션키가 반환되는 것을 볼 수 있다. Good!!

세션키 받아오는 헤더 확인

코드로 짜보자.

import requests

session = requests.Session()
res = session.get('https://etk.srail.kr/main.do')

print(res.headers)

아래는 결과다. 세션키가 잘 받아와진다.

{'Content-Language': 'ko-KR', 'Date': 'Mon, 08 Jan 2024 09:19:20 GMT', 'Set-Cookie': 'WMONID=R2C_d6DgmuN; Expires=Tue, 07-Jan-2025 18:19:20 GMT; Path=/, JSESSIONID_ETK=gmloZWafU1fOFQIUKeWLS6NAPfFcOHAO05w2Ig1D3hgNeJHVnK3FfYLq7TlH0UoQ.ZXRrcC9IRVRLQ09OMDItMw==; Path=/; Secure; HttpOnly; SameSite=None', 'Connection': 'keep-alive', 'Content-Type': 'text/html; charset=utf-8', 'Transfer-Encoding': 'chunked'}

 

SRT 로그인 페이지로 이동해서 로그인을 해보자.

 

  • URL : https://etk.srail.kr/cmc/01/selectLoginInfo.do
  • Query
    • pageId : 페이지 상세 정보; 값을 조금씩 바꿔보면 Bad Request가 뜨거나, 회원가입/로그인으로 변경된다. 파라미터 없이 보내도 응답이 오는걸로 봐서, 필요 없어보임
  • FormData
    • rsvTpCd, goUrl, from : 없어도 이상 없음
    • srchDvCd : 로그인 방식
      • 1 - 회원번호 로그인
      • 2 - 이메일 로그인
      • 3 - 휴대전화번호 로그인
    • srchDvNm : 회원번호/이베일/휴대전화번호
    • hmpgPwdCphd : 비밀번호

데이터를 보고 추측한 내용이니 틀릴 수 있음

 

로그인 코드를 짜보자!

login_type = '1'            # 1: 회원번호, 2: 이메일, 3: 휴대전화번호
login_id = ""     # 회원번호/이메일/휴대전화번호
login_pwd = ""    # 비밀번호

login_url = "https://etk.srail.kr/cmc/01/selectLoginInfo.do"
body = {
    "rsvTpCd": "",
    "goUrl": "",
    "from": "",
    "srchDvCd": login_type,
    "srchDvNm": login_id,
    "hmpgPwdCphd": login_pwd
}
res = session.post(login_url, data=body)

print(res.text)

 

id. passwd를 잘 넣어주면 아래와 같은 결과를 볼 수 있다.

<!DOCTYPE html>
<html lang="ko">
<head>
	<meta charset="utf-8" />
	<title></title>
	<meta http-equiv="imagetoolbar" content="no" />
	<meta http-equiv="Content-Script-Type" content="text/javascript" />
	<meta http-equiv="Content-Style-Type" content="text/css" />
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<meta http-equiv="Cache-Control" content="no-cache" />
	<meta http-equiv="Expires" content="0" />
	<meta http-equiv="Pragma" content="no-cache" />
</head>
<body>
	<script type="text/javascript">
	//<![CDATA[


	
		location.replace('/main.do');
	
	
	

	//]]>
	</script>
</body>
</html>

 

틀린 id나 passwd를 넣어보면 오류 내용이 포함된 다른 응답을 받을 수 있다.

성공 시 다르게 나오는 부분이

location.replace('/main.do');

이 코드인데, 이 텍스트가 없는 경우 로그인이 안됐다고 생각하고, 예외처리를 해주면 될 것 같다.

 

마지막으로, 로그인이 잘 됐는지 확인해보자.

로그인이 됐는지 확인하는 방법에는 여러가지가 있는데, 간단하게 메인페이지에서 '로그아웃' 버튼이 있으면 로그인 된걸로 확인해도 될 듯하다.

res = session.get("https://etk.srail.kr/main.do")

if '로그아웃' in res.text:
    print('로그인 성공')
else:
    print('로그인 실패')

id와 passwd를 바꿔가며 테스트를 해보니 아주 잘 동작한다!

 


지금까지 작성한 코드를 클래스해서 정리하면 아래와 같다!

 

import requests


class SRT:
    def __init__(self, login_type, login_id, login_pwd):
        # login_type - 1: 회원번호, 2: 이메일, 3: 휴대전화번호
        # login_id - 회원번호/이메일/휴대전화번호
        # login_pwd - 비밀번호

        self.session = requests.Session()
        self.session.get("https://etk.srail.kr/main.do")

        self.login_type = login_type
        self.login_id = login_id
        self.login_pwd = login_pwd

    def login(self):
        login_url = "https://etk.srail.kr/cmc/01/selectLoginInfo.do"
        body = {
            "rsvTpCd": "",
            "goUrl": "",
            "from": "",
            "srchDvCd": self.login_type,
            "srchDvNm": self.login_id,
            "hmpgPwdCphd": self.login_pwd
        }
        res = self.session.post(login_url, data=body)

        if "location.replace('/main.do')" in res.text:
            return True
        else:
            return False

    def is_logged_in(self):
        res = self.session.get("https://etk.srail.kr/main.do")

        if '로그아웃' in res.text:
            return True
        else:
            return False

if __name__ == "__main__":
    srt = SRT('1', '', '')
    print(srt.login())
    print(srt.is_logged_in())

[참고사이트]

 

세션(Session) 이용하는 방법

세션은 클라이언트 별로 서버에 저장되는 정보이다. 사용자 컴퓨터에 저장되던 쿠키와 다르게 서버에 저장되므로, 비교적 보안이 필요한 데이터는 쿠키보다 세션에 저장한다. 서버가 종료되거

enai.tistory.com