본문 바로가기
카테고리 없음

파이썬 크롤링 로그인 후 데이터 수집 실패

by heeday4753 2026. 3. 28.

크롤링을 하다 보면 로그인까지는 분명 성공한 것처럼 보이는데, 막상 회원 전용 페이지로 들어가면 다시 로그인 화면으로 돌아가는 경우가 있습니다. 처음에는 아이디나 비밀번호가 틀린 줄 알았지만 알고 보니 로그인 정보가 아니라 세션과 쿠키 유지 방식 문제였습니다. 이번 글에서는 로그인 후 데이터 접근이 왜 자꾸 실패하는지, requests.Session으로 어떻게 해결했는지 정리했습니다.

 

 

로그인 후 페이지 접근이 막히는 이유부터 이해해야 합니다

 

로그인 페이지 크롤링이 어려운 이유는 단순히 로그인 요청 한 번만 보내면 끝나는 구조가 아니기 때문입니다. 브라우저는 로그인에 성공하면 서버로부터 쿠키를 받고, 이후 다른 페이지에 접근할 때도 그 쿠키를 계속 함께 보냅니다. 서버는 이 쿠키를 보고 "이미 로그인한 사용자"라고 판단합니다. 그런데 requests.get()이나 requests.post()를 각각 따로 쓰면, 이전 요청에서 받은 쿠키가 다음 요청으로 이어지지 않습니다. 내 입장에서는 로그인을 했는데, 서버 입장에서는 처음 보는 방문자인 겁니다.

 

실제로 많이 겪는 증상은 세 가지입니다. 첫째, 로그인 요청은 200 응답이 나오는데 회원 페이지 접근 시 다시 로그인 페이지로 이동합니다. 둘째, 원하는 데이터 대신 "권한이 없습니다" 또는 "정상적인 접근이 아닙니다" 같은 문구가 나옵니다. 셋째, 리다이렉트가 반복되면서 주소는 바뀌는데 결국 원래 페이지에 도달하지 못합니다. 이런 증상이 나온다면 로그인 자체보다 "로그인 이후 상태가 유지됐는가"를 먼저 의심하는 게 맞습니다.

 

특히 초보자 입장에서는 개발자 도구에서 로그인 버튼을 눌렀을 때 요청이 한 번만 보이는 것처럼 느껴질 수 있습니다. 하지만 실제로는 로그인 페이지 진입, 보안 토큰 확인, 로그인 요청 전송, 세션 쿠키 발급, 리다이렉트 처리까지 여러 단계가 얽혀 있는 경우가 많습니다. 그래서 로그인 크롤링은 HTML 긁는 것보다 흐름 파악이 먼저입니다.

 

 

세션 개념을 이해하면 왜 Session 객체를 써야 하는지 보입니다

 

세션은 쉽게 말해 "이 사용자가 방금 전까지 무엇을 했는지 서버가 이어서 기억하게 만드는 연결 상태"라고 보면 이해하기 쉽습니다. 브라우저에서는 당연하게 유지되는 흐름이라 평소에는 의식하지 않지만, 크롤링 코드에서는 이 연결을 직접 관리해줘야 합니다. 이때 쓰는 게 requests.Session()입니다.

 

Session 객체를 쓰면 로그인 요청에서 받은 쿠키를 같은 세션 안에 저장하고, 이후 요청에도 자동으로 포함해 줍니다. 로그인 요청 따로, 데이터 수집 요청 따로가 아니라 같은 브라우저 창에서 계속 이어서 움직이는 것처럼 동작합니다. 이 차이 하나로 로그인 후 페이지 접근이 되느냐 안 되느냐가 갈립니다.

아래는 가장 기본적인 예시입니다.

import requests
from bs4 import BeautifulSoup

login_url = "https://example.com/login"
target_url = "https://example.com/mypage"

payload = {
    "user_id": "내아이디",
    "password": "내비밀번호"
}

with requests.Session() as session:
    login_response = session.post(login_url, data=payload)

    print("로그인 응답 코드:", login_response.status_code)
    print("현재 쿠키:", session.cookies.get_dict())

    target_response = session.get(target_url)
    print("회원 페이지 응답 코드:", target_response.status_code)
    print(target_response.url)

    soup = BeautifulSoup(target_response.text, "html.parser")
    print(soup.title.text if soup.title else "제목 없음")

 

핵심은 session.post()로 로그인한 뒤 같은 session으로 session.get()을 호출한다는 점입니다. requests.post()와 requests.get()을 따로 쓰면 쿠키가 이어지지 않아 다시 로그인 페이지로 튕깁니다.

 

추가로 확인해야 할 부분도 있습니다. 로그인 폼의 name 값이 실제로 user_id, password인지 개발자 도구에서 직접 확인해야 합니다. 화면에 보이는 입력창 이름과 서버에 전송되는 파라미터 이름이 다른 경우가 생각보다 많습니다. 또 일부 사이트는 CSRF 토큰 같은 숨겨진 값을 함께 보내야 로그인이 됩니다. 이럴 때는 로그인 페이지를 먼저 가져와 숨겨진 값을 추출한 뒤, 그 값을 포함해 로그인 요청을 보내야 합니다. Session은 기본이고, 사이트 구조 확인은 필수입니다.

 

 

로그인 크롤링은 코드보다 흐름을 맞추는 작업에 가깝습니다

 

"로그인 요청을 보냈다"와 "로그인 상태가 유지된다"는 다른 이야기입니다. 저도 처음에는 응답 코드만 보고 됐다고 생각했는데, 실제로는 쿠키가 다음 요청으로 이어지지 않아서 계속 튕기고 있었습니다. 복잡한 우회 기법이 필요한 게 아니라, 브라우저가 하던 동작을 코드에서도 똑같이 이어주면 됩니다.

 

로그인 크롤링이 막히면 무작정 코드부터 고치기 전에 순서대로 확인하는 게 낫습니다. 첫째, 로그인 후 쿠키가 생성되는지 확인합니다. 둘째, 같은 세션으로 다음 페이지에 접근했는지 확인합니다. 셋째, 이동한 최종 URL이 원했던 페이지인지 확인합니다. 넷째, HTML 안에 로그인 화면 문구가 다시 나타나는지 확인합니다. 이 네 가지만 봐도 원인이 꽤 빨리 나옵니다.


소개 및 문의 · 개인정보처리방침 · 면책조항

© 2026 블로그 이름