Skip to main content
Summary

한눈에 보기

Chrome DevTools Protocol(CDP)은 Chromium/Chrome 계열 브라우저를 바깥에서 관찰하고, 명령을 보내고, 내부 상태를 읽어오는 저수준 프로토콜이다.12 브라우저 자동화, 디버깅, 성능 분석, DOM 조작 같은 기능이 이 프로토콜 위에서 돌아간다.23

평소 F12로 여는 Chrome DevTools도 결국 CDP를 사용한다. Puppeteer와 Playwright 같은 도구도 CDP를 직접 쓰거나 감싼 형태로 브라우저를 제어한다.3 그래서 CDP를 이해하면 상위 도구가 내부에서 무엇을 하는지 더 또렷하게 보인다.

내가 이해한 핵심은 이렇다. CDP는 "브라우저와 대화하는 공용 언어"에 가깝고, DevTools나 자동화 라이브러리는 그 언어를 더 쓰기 쉽게 감싼 클라이언트다.23

pm-method

CDP란?

CDP는 Chromium, Chrome, 그리고 Blink 기반 브라우저를 계측하고 디버깅하고 자동화하기 위한 프로토콜이다.3 단순히 로그를 읽는 수준이 아니라, 페이지 이동, JavaScript 실행, 네트워크 관찰, 성능 추적까지 폭넓게 다룬다.13

중요한 점은 통신이 양방향이라는 것이다. 클라이언트는 브라우저에 명령을 보내고, 브라우저는 그에 대한 응답을 주거나 별도의 이벤트를 푸시한다.3 그래서 "요청하고 기다리는 구조"만이 아니라 "이벤트를 계속 구독하며 반응하는 구조"로 이해하는 편이 맞다.

실제로는 원격 디버깅 포트를 열고 WebSocket endpoint에 연결해 사용하는 경우가 많다.3 연결이 만들어지면 클라이언트는 그 소켓을 통해 CDP 메시지를 주고받는다.

덧붙이면, Chrome extension의 chrome.debugger API는 CDP를 다른 방식으로 실어 나르는 대체 전송 계층처럼 동작한다.2 즉, CDP 자체가 사라지는 것이 아니라 WebSocket 대신 확장 API를 통해 같은 계열의 명령과 이벤트를 다루는 셈이다.2

메시지 구조

CDP 메시지는 JSON-RPC와 매우 비슷한 형태를 가진다.3 완전히 똑같다고 보기보다, JSON-RPC 스타일을 가볍게 단순화한 프로토콜로 이해하면 편하다.

메시지는 크게 command, response, event로 나뉜다.3

command는 클라이언트가 브라우저에 보내는 요청이다. 여기에는 보통 id, method, params가 들어간다.3

response는 특정 command에 대한 응답이다. 보낸 id와 같은 id가 돌아오고, 실제 결과는 result에 담긴다.3

event는 브라우저가 비동기로 밀어주는 알림이다. 보통 id가 없고, method와 params만 온다.3

id는 요청과 응답을 연결하는 식별자다. method는 실행할 명령 이름이고, params는 입력값이다. result는 성공했을 때의 반환 데이터다.3 실무에서는 이벤트에 id가 없다는 점만 기억해도 흐름이 훨씬 잘 읽힌다.

// command
{
  "id": 1,
  "method": "Target.getTargets"
}

// response
{
  "id": 1,
  "result": {
    "targetInfos": []
  }
}

// event
{
  "method": "Target.targetCreated",
  "params": {
    "targetInfo": {
      "targetId": "abc",
      "type": "page"
    }
  }
}

핵심 개념

CDP를 이해할 때 가장 먼저 잡아야 할 개념은 Target이다. Target은 디버깅 대상 하나를 뜻하며, page, iframe, worker 같은 단위를 가리킨다.23 브라우저 전체가 아니라 "어느 대상과 대화하고 있는가"를 분리해서 다루는 방식이다.

그다음은 Session이다. 특정 target에 Target.attachToTarget으로 붙으면 그 target과 대화하기 위한 세션이 만들어지고, 이때 sessionId가 반환된다.13 이 sessionId가 있어야 이후 명령이 어느 대상에게 가야 하는지 정확히 지정할 수 있다.13

여기서 sessionId는 단순한 숫자표가 아니라 "특정 target과 열린 대화 채널의 ID"로 보는 게 좋다. 같은 브라우저 연결 안에서도 여러 target에 각각 다른 세션이 붙을 수 있기 때문이다.3

flatten: true는 지금 기준의 권장 방식이다. 공식 문서도 flat access를 기본 방향으로 설명하고 있고, non-flattened 모드는 폐기 예정으로 안내한다.1 flattened 모드에서는 메시지에 sessionId를 직접 넣어 하위 target 세션에 명령을 보낸다.13 예전의 중첩 전달 방식보다 구조가 단순하고 명확하다.

또 하나 중요한 점은 루트 브라우저 세션과 하위 세션의 관계다. WebSocket에 처음 연결했을 때 그 연결 자체가 암묵적인 루트 브라우저 세션처럼 동작한다.3 여기서 page target에 attach하면 page session이 생기고, 필요하면 다시 그 아래 관련 target으로 세션이 이어질 수 있다.3 부모 세션이 닫히면 자식 세션도 함께 정리된다는 점까지 포함해서, 세션은 단순한 토큰이 아니라 계층 구조를 가진다.3

대표 흐름

대표적인 CDP 사용 흐름은 보통 아래처럼 잡힌다.13

  • 브라우저를 remote debugging 모드로 실행한다.3

  • 브라우저가 노출한 WebSocket endpoint에 연결한다.3

  • Target.setDiscoverTargets 또는 Target.getTargets로 현재 target들을 찾는다.13

  • 필요한 target을 고른 뒤 Target.attachToTarget({ flatten: true })를 호출한다.13

  • 응답으로 받은 sessionId를 저장한다.13

  • 이후 Page.navigate, Runtime.evaluate 같은 도메인 명령을 sessionId와 함께 보낸다.3

  • Target.targetCreated, Network.*, Runtime.* 같은 이벤트를 계속 수신하며 상태 변화를 처리한다.3

실무에서는 Target.createTarget으로 새 페이지를 만들고, Target.getTargets로 확인하고, 필요하면 Target.setDiscoverTargets로 생성/변경 이벤트까지 추적하는 흐름이 자주 이어진다.13

주요 도메인 요약

Target은 디버깅 대상의 조회, 생성, attach/detach를 담당한다.1

Page는 페이지 이동, 로드, 스크린샷 같은 탭 수준 동작을 다룬다.3

Runtime은 JavaScript 실행과 실행 컨텍스트 관찰을 맡는다.23

DOM은 문서 구조 조회와 노드 단위 조작에 사용된다.2

CSS는 스타일 규칙 조회와 수정에 쓰인다.2

Network는 요청/응답 관찰, 헤더 확인, 네트워크 흐름 추적에 중요하다.2

Debugger는 스크립트 디버깅, 브레이크포인트, 스택 추적에 해당한다.2

Performance와 Tracing은 성능 지표 수집과 시간축 기반 추적에 쓰인다.2

도메인 이름이 곧 브라우저 기능 영역이라고 생각하면 이해가 쉽다. DevTools의 탭 구성이 CDP 도메인 구분과 꽤 자연스럽게 이어진다는 점도 기억할 만하다.3

실무에서 자주 하는 일

가장 흔한 작업은 페이지를 열고 이동하는 것이다. 새 탭을 만들거나 기존 page target에 붙은 뒤 Page.navigate를 호출하면 된다.13

DOM 조회와 조작도 자주 한다. 요소를 찾고 속성을 읽고, 필요하면 CSS나 DOM 도메인으로 화면 상태를 바꾼다.2

JavaScript 실행은 Runtime 계열 명령으로 처리한다. 단순 평가부터 실행 컨텍스트 단위 제어까지 가능해서, 자동화에서는 사실상 핵심 도구에 가깝다.2

네트워크 요청 관찰은 디버깅과 성능 분석에서 특히 중요하다. 어떤 요청이 나갔는지, 응답이 어떻게 왔는지, 특정 리소스가 왜 느린지 파악할 수 있다.2

성능 측정과 트레이싱은 로딩 병목, 스크립트 비용, 렌더링 구간을 볼 때 쓴다.2

워커와 iframe 추적은 생각보다 까다롭다. 특히 frame과 target이 항상 1:1이 아니기 때문에, 어떤 것은 새 target으로 보이고 어떤 것은 같은 target 안의 다른 실행 컨텍스트로 보인다.2 이 지점이 CDP 입문자가 가장 헷갈리기 쉬운 부분이다.

주의할 점

세션마다 상태가 따로 있을 수 있다. 예를 들어 Runtime.enable 같은 설정은 한 번만 켜면 전체 브라우저에 적용되는 것이 아니라, 세션 단위로 따로 활성화해야 할 수 있다.3 그래서 page session을 새로 만들었는데 이벤트가 안 오는 경우, 보통은 enable 상태를 그 세션에서 다시 잡아야 한다.

모든 도메인이 모든 target에서 되는 것도 아니다. 브라우저 세션에는 Page 도메인이 없을 수 있고, page session에는 page 관련 도메인이 열리지만 browser session과는 성격이 다르다.3 "어느 target에 붙어 있는가"가 곧 "무슨 명령이 가능한가"를 좌우한다.

experimental API는 자주 바뀔 수 있다. 공식 문서에서 experimental로 표시된 항목은 변경이나 제거 가능성을 전제로 보는 편이 안전하다.13

iframe과 target은 항상 1:1이 아니다. 같은 프로세스의 iframe은 별도 target이 아니라 같은 target 안의 다른 실행 컨텍스트로 나타날 수 있고, out-of-process iframe은 새 target이 될 수 있다.2 즉, frame을 따라간다고 해서 항상 attach 대상이 새로 생기는 것은 아니다.

직접 CDP를 쓰는 것이 항상 최선도 아니다. CDP는 강력하지만 저수준이기 때문에, 일반적인 자동화라면 Playwright나 Puppeteer 같은 상위 라이브러리가 더 생산적일 수 있다.3 CDP를 직접 쓰는 가치는 "더 깊은 제어"가 필요할 때 커진다.

간단 예시

아래는 "target 찾기 → attach → navigate" 흐름만 남긴 의사코드다.13

const ws = connect(browserWsEndpoint)

// 1) target 목록 조회
send({
  id: 1,
  method: "Target.getTargets"
})

const pageTargetId = pickPageTargetId()

// 2) page target에 attach
send({
  id: 2,
  method: "Target.attachToTarget",
  params: {
    targetId: pageTargetId,
    flatten: true
  }
})

const sessionId = getSessionIdFromResponse()

// 3) 해당 세션으로 페이지 이동
send({
  id: 1,
  sessionId,
  method: "Page.navigate",
  params: {
    url: "https://example.com"
  }
})

이 예시에서 중요한 부분은 두 가지다. Target.attachToTarget이 sessionId를 돌려준다는 점, 그리고 flattened 모드에서는 이후 명령에 sessionId를 실어 target별로 보낸다는 점이다.13

정리

  • CDP는 Chromium/Chrome을 디버깅하고 자동화하는 저수준 양방향 프로토콜이다.3

  • WebSocket 연결은 암묵적인 루트 브라우저 세션처럼 동작하고, target에 attach하면 하위 세션이 생긴다.3

  • Target.attachToTarget은 sessionId를 반환하며, flatten: true 방식이 현재 권장된다.13

  • 상태 활성화는 세션별로 분리될 수 있어서 Runtime.enable 같은 명령은 붙은 세션마다 다시 고려해야 한다.3

  • 일반 자동화는 Playwright/Puppeteer가 더 편할 수 있지만, CDP를 알면 브라우저 내부 동작을 더 정확하게 다룰 수 있다.3

참고

이 노트는 공식 문서를 중심으로, CDP 입문용 성격의 자료를 함께 참고해 정리했다.123

1Chrome DevTools Protocol - Target domain

2chrome.debugger API 문서

3Getting Started With Chrome DevTools Protocol

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기