AI 브라우저 도구로 네이버 블로그를 열 수 없을 때, 글은 Claude가 쓰고 발행은 내 컴퓨터의 Playwright 스크립트가 맡게 나눈 실제 구조입니다. 로그인 처리, 실제로 부딪힌 오류 3가지, 맥 launchd와 윈도우 작업 스케줄러·리눅스 cron 예약 방법까지 정리했습니다.
제가 실제로 쓰고 있는 네이버 블로그 자동 발행 구조를 정리했습니다. 결론부터 말하면 "글은 AI(Claude)가 쓰고, 발행은 내 컴퓨터의 스크립트가 한다"로 역할을 나눴더니 문제가 깔끔하게 풀렸습니다. 처음에는 맥에서 만들었지만, 같은 구조를 윈도우와 리눅스 컴퓨터에서 쓰는 방법도 함께 적었습니다.
왜 역할을 나눴나
처음 계획은 간단했습니다. Claude에게 브라우저 도구를 맡기고 "초안 쓰고 네이버 블로그에 올려 줘" 하면 끝날 줄 알았습니다. 티스토리와 이 사이트는 실제로 그렇게 운영하고 있었으니까요.
그런데 제 환경에서는 blog.naver.com이 Claude의 브라우저 도구(크롬 확장, 앱 내장 브라우저)에서 정책상 열리지 않았습니다. 버그가 아니라 의도된 제한이라, 우회 방법을 찾을 문제가 아니었습니다.
그래서 질문을 바꿨습니다. "AI가 네이버를 조작하게 만들 방법"이 아니라 "AI가 꼭 네이버를 직접 만져야 하나?"였습니다.
• 글을 기획하고 쓰는 건 AI가 잘하는 일입니다.
• 정해진 화면에 제목·본문·태그를 넣고 발행 버튼을 누르는 건 평범한 스크립트로 충분한 일입니다.
이렇게 나누니 AI는 네이버에 접속할 필요가 아예 없어졌습니다.
전체 구조 한눈에 보기
• 09:00 초안 작성: Claude 데스크톱 앱 예약 작업이 규칙 파일(state.json)대로 초안 .md를 쓰고 발행 대기열에 넣습니다.
• 변환: md2naver.py가 마크다운을 네이버 에디터용 HTML로 바꿉니다.
• 10:00 발행 실행: 컴퓨터의 예약 실행 도구(맥은 launchd)가 publish.mjs를 실행합니다. 대기열이 비어 있으면 바로 끝납니다.
• 발행: publish.mjs(Playwright)가 크롬으로 글쓰기 화면을 열고 제목·본문·카테고리·태그를 넣은 뒤 발행합니다.
• 기록: 발행된 글 주소를 state.json에 저장하고 대기열에서 뺍니다.
핵심은 state.json 하나로 AI와 스크립트가 소통한다는 점입니다. Claude는 대기열(pending_drafts)에 파일을 넣기만 하고, 스크립트는 거기 있는 것만 꺼내서 올립니다. 서로를 직접 부르지 않습니다.
로그인은 사람이, 딱 한 번만
가장 신경 쓴 부분은 로그인입니다. 스크립트에 아이디·비밀번호를 넣는 방식은 처음부터 뺐습니다.
• Playwright로 전용 크롬 프로필 폴더를 하나 만듭니다(launchPersistentContext).
• 처음 한 번 npm run login을 실행하면 크롬 창이 뜨고, 거기서 사람이 직접 로그인합니다('로그인 상태 유지' 체크).
• 이후에는 그 프로필의 로그인 상태를 그대로 쓰기 때문에 스크립트가 비밀번호를 다룰 일이 없습니다.
로그인이 풀리면 스크립트가 5분 동안 "직접 로그인해 주세요" 하고 기다리다가, 그래도 안 되면 실패로 끝납니다.
브라우저는 이미 설치된 구글 크롬을 그대로 씁니다(channel: 'chrome'). 그래서 브라우저를 따로 내려받지 않고 playwright-core 패키지 하나만 설치했습니다.
실제로 부딪힌 문제 3가지
처음부터 한 번에 된 건 아닙니다. 시험 발행을 돌리면서 나온 문제와 해결법입니다.
• 본문 붙여 넣기가 안 됐습니다: 에디터에 가짜 붙여 넣기(paste) 이벤트를 보내는 방식에 네이버 스마트에디터가 반응하지 않았습니다. 시스템 클립보드에 HTML을 넣고 붙여 넣기 단축키를 누르는 방식으로 한 번 더 시도하게 했더니 소제목·표·목록까지 그대로 들어갔습니다.
• 붙여 넣기가 두 번 될 뻔했습니다: 성공 여부를 판단하는 코드가 엉뚱한 요소를 보고 있어서, 실제로는 성공했는데도 재시도해 본문이 두 번 들어갈 수 있었습니다. 지금은 붙여 넣기 전후의 에디터 블록 개수를 세서 늘어났을 때만 성공으로 봅니다.
• 발행 대신 숨은 예약 발행 버튼을 눌렀습니다: "발행"이라는 글자로 버튼을 찾았더니 화면에 안 보이는 예약 발행 버튼이 먼저 잡혀 30초 동안 멈췄습니다. 화면에 보이는 버튼만 고르도록(:visible) 바꿔서 해결했습니다.
남의 서비스 화면을 자동화할 때는 첫 실행을 시험 실행(--dry-run: 다 채우고 마지막 발행 버튼만 안 누르기)으로 눈으로 확인하세요. 실패할 때 화면 캡처를 남기게 해 두면 고치는 데 몇 분이면 됩니다.
매일 알아서 돌게 만들기 (맥)
• 초안: Claude 데스크톱 앱 예약 작업으로 매일 09:00에 실행합니다. 2일에 1건을 쓰고, 컴퓨터가 꺼져 있어 밀리면 하루 최대 3건까지만 쓰고 나머지는 버립니다.
• 발행: 맥의 launchd에 매일 10:00로 등록했습니다. 올릴 글이 없으면 크롬도 띄우지 않고 바로 끝납니다.
• 맥이 잠자기 상태였다면 깨어났을 때 이어서 실행되고, 기록은 맥의 로그 폴더(~/Library/Logs)에 남습니다.
윈도우·리눅스 컴퓨터에서 쓰는 방법
이 구조는 맥 전용이 아닙니다. Node.js, 구글 크롬, playwright-core는 윈도우와 리눅스에서도 똑같이 돌아갑니다. 바꿀 부분은 세 가지뿐입니다.
• 붙여 넣기 단축키: 코드에 ⌘V를 직접 적지 말고 Playwright의 ControlOrMeta+V를 쓰세요. 맥에서는 ⌘V, 윈도우·리눅스에서는 Ctrl+V로 자동으로 바뀝니다.
• 파일 경로: 프로필 폴더·대기열 경로를 /Users/... 처럼 고정하지 말고 Node의 path.join으로 스크립트 위치 기준으로 만드세요. 윈도우는 경로 구분 문자가 다릅니다.
• 예약 실행 도구: 맥의 launchd 자리에 각 운영체제의 예약 도구를 씁니다.
윈도우에서는 작업 스케줄러(Task Scheduler)를 씁니다. 화면에서 "기본 작업 만들기 → 매일 10:00 → 프로그램 시작"을 고르고 프로그램에 npm, 인수에 run publish, 시작 위치에 프로젝트 폴더를 넣으면 됩니다. 명령 한 줄로 등록하려면 명령 프롬프트에서 아래처럼 입력합니다(경로는 내 프로젝트 폴더로 바꿉니다).
schtasks /create /tn "NaverBlogPublish" /sc daily /st 10:00 /tr "cmd /c cd /d C:\naver-blog && npm run publish >> publish.log 2>&1"
등록한 작업의 속성 → 설정 탭에서 "예약된 시작 시간을 놓친 경우 가능한 대로 빨리 작업 시작"을 켜 두면, 10시에 컴퓨터가 꺼져 있었을 때 켜진 뒤 이어서 실행됩니다. 작업은 "사용자가 로그온할 때만 실행"으로 두세요. 크롬 창을 띄워야 하므로 로그인된 화면이 있어야 합니다.
리눅스(우분투 등 데스크톱 환경)에서는 crontab -e로 아래 한 줄을 넣는 방법이 가장 간단합니다.
0 10 * * * cd ~/naver-blog && npm run publish >> ~/naver-blog/publish.log 2>&1
꺼져 있던 시간을 이어서 실행하고 싶다면 systemd 사용자 타이머(OnCalendar=*-*-* 10:00, Persistent=true)를 쓰면 됩니다. 이 방식은 크롬 창을 띄우므로 화면이 없는 서버가 아니라 로그인된 데스크톱에서 실행해야 하고, cron에서 실행할 때는 DISPLAY 같은 화면 환경 변수를 함께 넘겨야 할 수 있습니다.
초안 쪽도 같습니다. Claude 예약 작업을 쓰지 않는 환경이라면 AI와 대화해 만든 원고를 drafts 폴더에 넣고 대기열에 이름만 추가해도 됩니다. 발행 스크립트는 누가 원고를 넣었는지 상관하지 않습니다.
써 보고 느낀 점과 주의할 점
AI에게 모든 걸 맡기려 하지 않는 게 오히려 자동화의 핵심이었습니다. 막힌 곳을 억지로 뚫는 대신 AI가 잘하는 일(기획·글쓰기·사실 확인)과 스크립트가 잘하는 일(정해진 버튼 누르기)을 나눴더니 더 안정적이었고, 로그인 같은 민감한 부분도 사람 손에 남길 수 있었습니다.
• 네이버 운영정책을 먼저 확인하세요. 자동화 도구로 같은 글을 대량으로 올리거나 스팸처럼 쓰면 제재를 받을 수 있습니다. 저는 제 계정에, 이틀에 한 편, 직접 검수할 수 있는 글만 올리는 용도로 씁니다.
• 에디터 화면은 언제든 바뀝니다. 버튼 이름이나 구조가 바뀌면 스크립트가 멈출 수 있으니 실패 캡처와 로그를 꼭 남기세요.
• 아이디·비밀번호는 코드에 넣지 마세요. 전용 프로필에 직접 로그인하는 것으로 충분합니다.
"AI는 그 사이트에 못 들어가요"라는 벽을 만났다면, AI가 꼭 그 사이트에 들어가야 하는지부터 다시 생각해 보세요. 생각보다 많은 경우 글은 AI가, 버튼은 내 컴퓨터가 정답일 수 있습니다.
Claude Code를 처음 설치하다 막혔다면 Claude Code 설치 오류 해결을, AI에게 원고를 맡길 때 요청문을 다듬고 싶다면 프롬프트 잘 쓰는 법을 함께 보세요. 단계별로 배우고 싶다면 학습 가이드에서 시작할 수 있습니다.
참고한 자료
Playwright — BrowserType (launchPersistentContext, channel) (checked Oct 14, 2026) ↗
Playwright — Keyboard (ControlOrMeta) (checked Oct 14, 2026) ↗
Microsoft — Task Scheduler (checked Oct 14, 2026) ↗
Apple — Scheduling Timed Jobs (launchd) (checked Oct 14, 2026) ↗
