IT/개발

Python Playwright와 Kakao OAuth로 티스토리 자동 포스팅 파이프라인 구축하기

zzun 2026. 4. 26. 01:25
반응형

IT·보안·개발 분야 전문가로서, 반복적인 수작업을 자동화하는 것은 생산성 향상의 핵심입니다. 블로그 포스팅 역시 마찬가지입니다. 수많은 콘텐츠를 꾸준히 발행해야 하는 상황에서, 매번 웹사이트에 접속하여 로그인하고, 내용을 붙여 넣고, 태그를 입력하는 과정은 상당한 시간과 노력을 소모합니다. 오늘은 이러한 비효율을 해결하기 위해 Python Playwright와 Kakao OAuth를 활용한 티스토리 자동 포스팅 시스템 구축 과정을 심층적으로 다루고자 합니다. 이 파이프라인은 단순한 자동화를 넘어, 안정적이고 확장 가능한 시스템을 목표로 합니다.

이 글을 통해 독자 여러분은 실제 업무에 바로 적용할 수 있는 자동화 시스템 개발 노하우와 마주할 수 있는 문제 해결 방안에 대한 실질적인 인사이트를 얻게 될 것입니다.

1. 티스토리 자동 포스팅, 왜 필요한가?

콘텐츠 마케팅, 기술 문서화, 개인 포트폴리오 관리 등 다양한 이유로 블로그 포스팅은 현대 개발자 및 IT 전문가에게 필수적인 활동이 되었습니다. 그러나 수동 포스팅은 다음과 같은 문제점을 야기합니다:

  • 시간 소모: 로그인, 편집기 진입, 내용 입력, 태그 설정 등 반복적인 과정에 드는 시간은 누적될수록 상당합니다.
  • 휴먼 에러: 수동 작업은 오탈자, 태그 누락, 카테고리 설정 오류 등 사람의 실수로 이어질 수 있습니다.
  • 확장성 부족: 다수의 블로그를 관리하거나, 대량의 콘텐츠를 일괄적으로 발행해야 할 때 수동 방식은 한계에 부딪힙니다.

이러한 문제를 해결하기 위해 웹 브라우저 자동화 도구인 Playwright안전하고 편리한 인증 방식인 Kakao OAuth를 결합하여 견고한 자동 포스팅 파이프라인을 구축할 수 있습니다. 이는 개발된 콘텐츠를 효율적으로 배포하고, 핵심 업무에 집중할 수 있도록 돕는 강력한 도구가 될 것입니다.

2. 핵심 기술 스택 이해: Playwright와 Kakao OAuth

2.1. Python Playwright: 차세대 브라우저 자동화 도구

Playwright는 Microsoft에서 개발한 강력한 웹 브라우저 자동화 라이브러리로, Chromium, Firefox, WebKit 등 모든 주요 브라우저를 하나의 API로 제어할 수 있습니다. Python은 물론 JavaScript, Java, C# 등 다양한 언어를 지원합니다.

기존의 Selenium과 비교했을 때 Playwright는 다음과 같은 장점을 가집니다:

  • 단일 API로 크로스 브라우저 지원: 여러 브라우저를 별도 설정 없이 테스트하거나 자동화할 수 있습니다.
  • 자동 대기 기능: 요소가 나타나거나 액션이 완료될 때까지 자동으로 기다려주므로, 비동기 웹 페이지에서 발생할 수 있는 타이밍 문제를 효과적으로 줄여줍니다.
  • Context와 Page 개념: 격리된 브라우저 환경(Context)과 탭(Page)을 쉽게 관리할 수 있어, 로그인 세션 유지 등에 유리합니다.
  • 다양한 상호작용: 클릭, 입력, 드래그 앤 드롭, 파일 업로드 등 실제 사용자의 다양한 동작을 정교하게 모방할 수 있습니다.
  • 스크린샷 및 비디오 녹화: 자동화 과정 중 발생하는 문제 디버깅에 매우 유용합니다.

티스토리와 같이 동적이고 자바스크립트를 많이 사용하는 웹사이트에서 Playwright는 안정적이고 효율적인 자동화를 가능하게 하는 최적의 선택입니다.

2.2. Kakao OAuth: 안전하고 간편한 인증

티스토리는 카카오 계정 로그인을 기본으로 제공합니다. 여기서 Kakao OAuth는 직접적으로 티스토리 비밀번호를 스크립트에 노출하지 않고 카카오 계정으로 로그인할 수 있도록 하는 핵심적인 역할을 합니다. 엄밀히 말해, 여기서는 'Kakao OAuth'의 전체 인증 흐름을 통해 액세스 토큰을 발급받아 Tistory API를 직접 호출하는 방식보다는, Playwright를 이용해 카카오 로그인 페이지를 자동화하여 Tistory에 접속하는 방식에 중점을 둡니다. 이는 Tistory의 비공개 API를 역분석하는 위험을 감수하지 않고도 안전하게 접근하는 현실적인 방법입니다.

Playwright는 카카오 로그인 페이지로 이동하여 이메일과 비밀번호를 입력하고, '로그인' 버튼을 클릭하는 일련의 과정을 자동화합니다. 이 과정에서 2단계 인증과 같은 추가 보안 절차가 있다면, 해당 절차도 스크립트 로직에 포함하여 처리해야 합니다. 하지만 대부분의 경우, Playwright는 사용자 계정 정보를 환경 변수 등으로 안전하게 관리하면서 로그인 과정을 매끄럽게 수행할 수 있습니다.

3. 자동 포스팅 시스템 개발 과정 상세

3.1. 환경 설정 및 Playwright 초기화

가장 먼저 Python 환경을 설정하고 필요한 라이브러리를 설치해야 합니다. 가상 환경을 활성화한 후, Playwright를 설치합니다.

pip install playwright

다음으로, Playwright가 제어할 브라우저를 설치합니다.

playwright install chromium

이제 기본적인 Playwright 스크립트를 작성할 준비가 되었습니다. `sync_playwright`를 사용하여 동기 API를 호출하고 브라우저 인스턴스를 생성합니다.

from playwright.sync_api import sync_playwright
import time

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True) # 개발 시에는 headless=False로 설정하여 브라우저 동작 확인
    page = browser.new_page()
    # ... 이후 자동화 로직 ...
    browser.close()

3.2. Kakao 로그인 자동화

티스토리 블로그 접속을 위해서는 카카오 로그인이 필수입니다. Playwright는 실제 사용자가 로그인하는 것과 동일한 방식으로 카카오 로그인 페이지와 상호작용합니다.

  • 로그인 페이지 접속: 먼저 티스토리 로그인 페이지로 이동합니다. 이때, '카카오 계정으로 로그인' 버튼을 클릭하여 카카오 로그인 화면으로 리다이렉트되도록 합니다.
  • 이메일 및 비밀번호 입력: 카카오 로그인 페이지에서 이메일 입력 필드와 비밀번호 입력 필드의 CSS 셀렉터 또는 XPath를 찾아 Playwright의 `page.fill()` 메서드를 사용하여 정보를 입력합니다. 이때, 민감한 정보는 환경 변수(`os.environ`)를 통해 관리하여 코드에 직접 노출되지 않도록 합니다.
  • 로그인 버튼 클릭: 로그인 버튼의 셀렉터를 찾아 `page.click()` 메서드로 클릭합니다.
  • 세션 유지: 로그인 성공 후 `page.context.storage_state(path='state.json')`를 사용하여 현재 로그인 세션의 상태를 파일로 저장할 수 있습니다. 다음 실행 시 이 `state.json` 파일을 `browser.new_context(storage_state='state.json')`로 로드하면 로그인 과정을 생략하고 바로 접속할 수 있어 매우 효율적입니다. 이 파일은 민감한 정보를 포함하므로 보안에 유의해야 합니다.

3.3. 티스토리 포스팅 에디터 상호작용

로그인에 성공하면 블로그의 글쓰기 페이지로 이동합니다. 티스토리 에디터는 일반적으로 웹 표준을 따르지만, Rich Text Editor의 특성상 `iframe` 내부에 있거나 `contenteditable` 속성을 가진 `div` 요소로 구현되는 경우가 많습니다. 이러한 요소에 내용을 입력하는 방식은 일반적인 `input` 태그와는 다릅니다.

  • 글쓰기 페이지 이동: `page.goto(f'https://{BLOG_NAME}.tistory.com/manage/post')`와 같이 직접 글쓰기 URL로 이동하거나, 블로그 메인 페이지에서 '새 글쓰기' 버튼을 클릭하여 이동합니다.
  • 제목 입력: 제목 입력 필드(`input` 태그)를 찾아 `page.fill('input[id='post-title']', '나의 자동화된 블로그 포스트')`와 같이 입력합니다. ID, name, class 등 안정적인 셀렉터를 사용합니다.
  • 본문 입력: 본문은 가장 까다로운 부분입니다. 만약 `textarea`라면 `page.fill()`을 사용하면 되지만, 대부분 `div` 요소에 `contenteditable='true'` 속성이 부여된 Rich Text Editor일 것입니다. 이 경우, `page.evaluate()`를 사용하여 JavaScript 코드를 직접 실행하여 `innerHTML` 속성을 설정하는 것이 효과적입니다.

page.evaluate("document.querySelector('.editor-content-viewer').innerHTML = '본문의 HTML 내용을 여기에 입력합니다.'")

  • 태그 입력: 태그 입력 필드를 찾아 `page.fill()`로 태그를 입력한 후, 엔터 키를 누르거나 '추가' 버튼을 클릭하는 방식으로 태그를 추가합니다. 여러 태그를 한 번에 입력해야 한다면 쉼표로 구분하여 입력하고 `keyboard.press('Enter')`를 활용할 수 있습니다.
  • 카테고리 선택: 카테고리 드롭다운 메뉴를 클릭하여 펼친 후, 원하는 카테고리 항목의 셀렉터를 찾아 클릭합니다. `page.select_option()` 메서드를 사용할 수도 있습니다.
  • 발행 또는 저장: 최종적으로 '발행' 또는 '임시저장' 버튼을 찾아 `page.click()`으로 작업을 완료합니다. 발행 전에는 충분한 대기 시간(`time.sleep()`)을 두거나, 발행 완료 메시지를 기다리는 로직을 추가하여 안정성을 높입니다.

4. 문제 해결 및 베스트 프랙티스

4.1. 동적 UI 요소 및 셀렉터 문제

웹 페이지는 끊임없이 업데이트되며, UI 요소의 ID나 클래스 이름이 변경될 수 있습니다. 이로 인해 스크립트가 멈추거나 오작동할 수 있습니다. 이를 해결하기 위한 전략은 다음과 같습니다:

  • 안정적인 셀렉터 사용: 변경될 가능성이 적은 ID 속성, 또는 상대적으로 안정적인 클래스 이름, HTML 구조를 활용한 XPath 등을 우선적으로 고려합니다.
  • `text=` 셀렉터 활용: 버튼이나 링크처럼 텍스트 내용이 고정적인 요소는 `page.click('text=발행')`과 같이 텍스트 기반 셀렉터를 사용할 수 있습니다.
  • 속성 기반 셀렉터: `input[placeholder='제목을 입력하세요']`와 같이 특정 속성 값을 기반으로 요소를 찾습니다.

4.2. 비동기 처리 및 대기 전략

현대 웹 페이지는 비동기적으로 콘텐츠를 로드하므로, 요소가 나타나기 전에 스크립트가 다음 동작을 시도하면 오류가 발생합니다. Playwright는 이를 위한 강력한 기능을 제공합니다:

  • `page.wait_for_selector()`: 특정 셀렉터의 요소가 DOM에 나타날 때까지 기다립니다.
  • `page.wait_for_load_state('networkidle')`: 네트워크 활동이 없을 때까지 기다려 페이지 로드가 완료되었음을 확인합니다.
  • `time.sleep()`: 최후의 수단으로, 명시적인 대기 시간을 설정할 수 있지만, 웹 페이지의 로드 속도에 따라 불안정할 수 있으므로 권장되지 않습니다.

4.3. 세션 관리 및 에러 핸들링

  • 세션 유지: 위에서 언급했듯이 `storage_state`를 사용하여 로그인 세션을 파일로 저장하고 재사용하면 매번 로그인하는 번거로움을 줄일 수 있습니다. 다만, 세션 파일의 보안에 각별히 유의해야 합니다.
  • 견고한 에러 핸들링: `try-except` 블록을 사용하여 요소가 발견되지 않거나 네트워크 오류가 발생했을 때 적절히 예외를 처리합니다. 실패 시 스크린샷을 찍거나 로그를 남겨 디버깅 정보를 확보하는 것이 좋습니다.
  • `headless` 모드 활용: 개발 및 디버깅 단계에서는 `headless=False`로 설정하여 실제 브라우저가 동작하는 모습을 보며 문제를 파악합니다. 배포 단계에서는 `headless=True`로 설정하여 리소스 소모를 줄입니다.

4.4. 보안 고려사항

스크립트에 카카오 계정 정보(이메일, 비밀번호)를 직접 하드코딩하는 것은 매우 위험합니다. 반드시 다음과 같은 방식으로 관리해야 합니다:

  • 환경 변수 사용: `os.environ.get('KAKAO_EMAIL')`과 같이 환경 변수에서 값을 읽어옵니다.
  • `.env` 파일 활용: `python-dotenv` 라이브러리를 사용하여 `.env` 파일에 민감한 정보를 저장하고 `.gitignore`에 추가하여 버전 관리 시스템에서 제외합니다.

결론

Python Playwright와 Kakao OAuth를 활용한 티스토리 자동 포스팅 파이프라인은 단순 반복 작업을 자동화하여 개발자의 생산성을 크게 향상시킬 수 있는 강력한 도구입니다. 이 시스템은 콘텐츠 배포의 효율성을 극대화하고, 인간의 실수를 줄이며, 궁극적으로는 개발자가 더 중요한 문제 해결에 집중할 수 있도록 돕습니다.

물론, 웹 페이지의 UI 변경이나 보안 정책 업데이트에 따라 스크립트 수정이 필요할 수 있습니다. 하지만 Playwright의 강력한 기능과 유연한 에러 핸들링 전략을 통해 이러한 변화에 효과적으로 대응할 수 있습니다. 나아가 이 파이프라인에 AI 기반 콘텐츠 생성 모듈이나 스케줄링 기능을 통합한다면, 단순 자동화를 넘어선 지능형 콘텐츠 관리 시스템으로 발전시킬 수 있을 것입니다. 지금 바로 여러분의 반복적인 포스팅 작업을 자동화하여, 더 높은 효율성을 경험해 보시기 바랍니다.

반응형