
애드센스 승인을 목표로 티스토리 블로그를 꾸준히 운영하기로 했다. 글쓰기 과정을 효율화하면 좋겠다는 생각에 자동화를 구상했다. 처음엔 당연히 공식 API가 있을 줄 알고 찾아봤다.
티스토리 API, 벌써 죽었니? 😱
문제는 여기서부터 시작됐다. 있을 거라 확신했던 티스토리 오픈 API는 이미 서비스 종료 상태였다.
문서를 찾아보니 모든 엔드포인트에 deprecated 딱지가 붙어 있었다. 이걸 확인하는 순간 머리가 띵했다.
그렇다면 남은 길은 브라우저 자동화뿐. 바로 Playwright를 꺼내 들었다.
예상치 못한 장벽에 부딪혔지만, 뭐, 개발자에게 이런 건 일상이다.
덕분에 새로운 도전을 시작했다.
카카오 로그인 세션, 왜 자꾸 말썽일까? 🤔
Playwright로 처음 시도한 건 헤드리스 모드였다. 백그라운드에서 조용히 작업이 끝나면 좋겠다는 생각이었다.
그런데 로그인만 하면 자꾸 세션이 풀리는 현상이 발생했다. 처음엔 내 코드 문제인가 싶어 몇 번이나 다시 확인했다. 명시적인 로그아웃 처리 같은 건 없었는데도 말이다.
원인을 파고드니 카카오 로그인이 문제였다. 헤드리스 모드는 매번 새로운 브라우저 인스턴스를 띄우는 것과 같았다. 카카오 입장에선 매번 "새 기기"에서 로그인 시도를 하는 셈이니, 보안을 위해 세션을 계속 끊어버리는 거였다.
해결책은 의외로 간단했다. headless: false 옵션이었다.
브라우저 창을 띄운 채로 자동화를 돌리자, 카카오가 한 번 인정한 기기라고 판단했는지 세션이 잘 유지됐다. 자원 소모는 좀 늘었지만, 안정적인 로그인을 얻었다. 성능보다 안정성이 우선인 경우가 많다는 걸 다시금 깨달았다.
헤드리스 문제를 해결하고 나니 또 다른 세션 문제가 나타났다. 브라우저를 닫았다 열면 티스토리 자체 세션은 풀려버리는데, 카카오 간편로그인 세션은 남아있는 상황이었다. 매번 아이디와 비밀번호를 입력하게 할 수는 없었다.
로그인 페이지에 진입했을 때, 티스토리 자체 로그인은 풀려도 카카오 계정 타일이 남아있는 걸 확인했다. 이 상태에서 계정 타일을 클릭하는 것만으로 무인 통과가 가능했다.
결국, 로그인 페이지에 도달하면 우선 카카오 계정 타일이 있는지 확인하고, 있다면 그걸 클릭하는 로직을 추가했다. 타일이 없으면 그때서야 ID/PW를 입력하는 풀 로그인을 시도하게 만들었다.
덕분에 불필요한 로그인 정보 입력 단계를 건너뛸 수 있었다. 인증 흐름을 뜯어보고 나니, 각 세션의 생명주기가 달라서 생긴 일이었다.
티스토리 에디터의 숨겨진 비밀 (사진 버튼 찾기) 🤣
티스토리 에디터에서 사진을 추가하는 버튼을 찾는 게 다음 고비였다. 처음엔 너무 당연하게 button 태그나 input[type="button"]으로 찾으려 했다. aria-label 속성도 짐작해서 시도했지만 계속 헛발질이었다.
개발자 도구로 대충 찾아봐도 뭐가 뭔지 헷갈렸다.
결국 직접 DOM 탐색 스크립트를 만들었다. 원하는 영역 근처의 모든 요소를 재귀적으로 탐색하면서 태그, ID, 클래스, aria-label 같은 속성을 모조리 출력하는 스크립트였다.

이걸 돌려보니 div 태그인데 mceu_0 같은 클래스와 aria-label="사진"을 가진 녀석이 눈에 띄었다. 이놈이 범인이었다.
단순한 버튼이 아니라 TinyMCE 같은 위지윅 에디터에서 사용하는 커스텀 UI 컴포넌트였던 것이다. 너무 쉽게 생각했다가 시간을 꽤 날렸다. 눈으로 보이는 게 다가 아니라는 교훈을 얻었다.
빈 문단에 커서 놓기... Range API의 신세계!
마지막으로 겪었던 삽질은 빈 문단에 커서를 놓는 문제였다. 글 내용을 입력하기 전에 특정 빈 <p> 태그에 커서를 두고 싶었다.
Playwright의 click() 메서드를 호출했는데, 자꾸 "요소를 찾을 수 없거나 클릭할 수 없다"는 에러가 떴다.
원인은 빈 <p> 태그는 시각적으로 클릭할 만한 영역이 없기 때문이었다. 브라우저가 사용자 클릭을 인식하는 방식과 프로그래밍적으로 캐럿을 위치시키는 방식 사이의 간극이었다.
해결책은 page.evaluate()를 사용해 직접 JavaScript의 Range API를 호출하는 거였다. 특정 p 태그 안에 선택 영역을 만들고, 그 영역을 시작점이나 끝점으로 축소하여 커서를 위치시키는 방식이다.
await page.evaluate(selector => {
const element = document.querySelector(selector);
if (element) {
const range = document.createRange();
range.selectNodeContents(element);
range.collapse(false); // 선택 영역을 끝점으로 축소
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
}, '.target-empty-paragraph'); // 빈 문단을 식별하는 셀렉터
이렇게 직접 DOM을 조작하니 비로소 원하는 대로 커서를 움직일 수 있었다. 브라우저 자동화가 표면적인 UI 인터랙션만 다루는 것이 아니라, 때로는 내부적인 DOM과 자바스크립트까지 파고들어야 할 때가 있다는 걸 다시 한번 배웠다.
티스토리 글쓰기 자동화를 만들면서 겪은 삽질은 하나하나가 소중한 경험이었다. 단순해 보이는 작업도 파고들면 예상치 못한 복잡성을 만난다.
하지만 그 과정을 통해 웹 페이지의 동작 방식, 인증 시스템의 미묘한 차이, 위지윅 에디터의 특성 등 여러 지식을 얻었다. 자동화는 단순 반복 작업 해방을 넘어, 숨겨진 기술적 난관을 해결하는 과정 자체가 재미있는 여정이었다.
※ 이 글은 직접 겪은 작업 경험을 바탕으로 AI의 도움을 받아 작성했습니다.