Skip to content

빠른 시작: Mbbrowser 환경 제어하기

이 장에서는 세 가지 언어에 대해 실행 가능한 완전한 스크립트를 제공합니다. 가장 익숙한 언어를 선택하여 따라와 주십시오. 핵심 로직은 동일합니다. ApiServer에 ws 주소를 요청한 다음, connectOverCDP를 사용하여 Mbbrowser의 제어권을 가져오는 것입니다.


방법 1: JavaScript / Node.js 버전

start.js라는 이름의 파일을 만듭니다.

javascript
const { chromium } = require('playwright');
const axios = require('axios');

// ============================
// 설정 (본인의 실제 정보로 채워주세요)
// ============================
const API_URL    = 'http://127.0.0.1:8186';
const SESSION_ID = '사용자_환경_ID_입력';   // Mbbrowser 환경 우클릭 → 환경 ID 복사

async function main() {
  // ── 1단계: ApiServer에 특정 환경을 열도록 요청 ────────────────────
  console.log('⏳ Mbbrowser 환경을 여는 중...');
  let wsEndpoint;
  try {
    const response = await axios.post(`${API_URL}/api/v1/browser/start`, {
      Session_ID: SESSION_ID
    });
    if (response.data.code !== 0) {
      console.error('❌ 환경 시작 실패:', response.data.message);
      return;
    }
    // ── 2단계: WebSocket 주소 추출 (Playwright 전용 필드) ───────────
    wsEndpoint = response.data.data.ws;
    console.log('✅ 환경이 열렸습니다. ws 주소:', wsEndpoint);
  } catch (err) {
    console.error('❌ ApiServer에 연결할 수 없습니다. 실행 중인지 확인하세요!', err.message);
    return;
  }

  // ── 3단계: connectOverCDP를 사용하여 제어권 획득 ─────────────────
  const browser = await chromium.connectOverCDP(wsEndpoint);
  console.log('🎉 Playwright 제어 성공!');

  try {
    // ── 4단계: 현재 컨텍스트와 페이지 가져오기 ────────────────────
    // Mbbrowser 환경에는 기본 컨텍스트가 있으므로 첫 번째 것을 사용합니다.
    const context = browser.contexts()[0];
    const page    = context.pages()[0] || await context.newPage();

    // ── 5단계: 비즈니스 작업 실행 ─────────────────────────────
    await page.goto('https://www.mbbrowser.com', { waitUntil: 'domcontentloaded' });
    console.log('📄 현재 페이지 타이틀:', await page.title());

    // 관찰을 위해 3초 대기
    await page.waitForTimeout(3000);

    console.log('✅ 스크립트 실행 완료!');
  } finally {
    // Playwright 연결 해제 (Mbbrowser 창은 계속 실행됨)
    await browser.close();
  }
}

main().catch(console.error);

실행:

bash
node start.js

방법 2: Python 버전

start_playwright.py라는 이름의 파일을 만듭니다.

python
import requests
from playwright.sync_api import sync_playwright

# ============================
# 설정
# ============================
API_URL    = "http://127.0.0.1:8186"
SESSION_ID = "사용자_환경_ID_입력"


def get_ws_endpoint(session_id: str) -> str or None:
    """Mbbrowser ApiServer를 호출하여 환경을 시작하고 ws 주소를 반환합니다."""
    print("⏳ Mbbrowser 환경을 여는 중...")
    try:
        resp = requests.post(
            f"{API_URL}/api/v1/browser/start",
            json={"Session_ID": session_id},
            timeout=30
        )
        data = resp.json()
    except requests.exceptions.ConnectionError:
        print("❌ ApiServer에 연결할 수 없습니다! apiserver.exe가 실행 중인지 확인하세요.")
        return None

    if data.get("code") != 0:
        print(f"❌ 환경 시작 실패: {data.get('message')}")
        return None

    ws = data["data"]["ws"]
    print(f"✅ 환경이 열렸습니다. ws 주소: {ws}")
    return ws


def main():
    ws_endpoint = get_ws_endpoint(SESSION_ID)
    if not ws_endpoint:
        return

    with sync_playwright() as p:
        # ── connect_over_cdp를 통해 제어권 획득 ─────────────────
        browser = p.chromium.connect_over_cdp(ws_endpoint)
        print("🎉 Playwright 제어 성공!")

        # 기존의 기본 BrowserContext 가져오기 (모든 쿠키, 저장소 유지)
        context = browser.contexts[0]
        # 첫 번째 페이지 가져오기. 없으면 새로 생성
        page = context.pages[0] if context.pages else context.new_page()

        # ── 비즈니스 작업 실행 ──────────────────────────────────────────
        page.goto("https://www.mbbrowser.com", wait_until="domcontentloaded")
        print(f"📄 현재 페이지 타이틀: {page.title()}")

        page.wait_for_timeout(3000)
        print("✅ 스크립트 실행 완료!")

        browser.close()


if __name__ == "__main__":
    main()

실행:

bash
python start_playwright.py

방법 3: Java 버전

NOTE

Java 버전의 경우 Mbbrowser 클라이언트의 자동화 스크립트 관리자 사용을 권장합니다. 이는 Playwright JAR 번들과 드라이버 추출을 자동으로 처리합니다. 다음 코드는 스크립트 에디터에서 직접 사용할 수 있는 예시입니다.

java
import com.microsoft.playwright.*;
import java.net.URI;
import java.net.http.*;
import org.json.*;

public class MBPlaywright {
    static final String API_URL    = "http://127.0.0.1:8186";
    static final String SESSION_ID = "사용자_환경_ID_입력";

    public static void main(String[] args) throws Exception {
        // ── 1단계: ApiServer를 호출하여 환경 시작 ────────────────────
        System.out.println("⏳ Mbbrowser 환경을 여는 중...");
        HttpClient httpClient = HttpClient.newHttpClient();
        String body = "{\"Session_ID\":\"" + SESSION_ID + "\"}";
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(API_URL + "/api/v1/browser/start"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
        HttpResponse<String> response = httpClient.send(
            request, HttpResponse.BodyHandlers.ofString()
        );

        JSONObject data   = new JSONObject(response.body());
        String wsEndpoint = data.getJSONObject("data").getString("ws");
        System.out.println("✅ 환경이 열렸습니다. ws: " + wsEndpoint);

        // ── 2단계: Playwright connectOverCDP 제어 ────────────────────
        // 내장 브라우저 다운로드 생기 방지 설정
        System.setProperty("playwright.skip.browser.download", "1");

        try (Playwright playwright = Playwright.create()) {
            Browser browser = playwright.chromium().connectOverCDP(wsEndpoint);
            System.out.println("🎉 Playwright 제어 성공!");

            BrowserContext context = browser.contexts().get(0);
            Page page = context.pages().isEmpty()
                ? context.newPage()
                : context.pages().get(0);

            page.navigate("https://www.mbbrowser.com");
            System.out.println("📄 현재 페이지 타이틀: " + page.title());

            Thread.sleep(3000);
            System.out.println("✅ 스크립트 실행 완료!");

            browser.close();
        }
    }
}

코드 분석

connectOverCDP vs launch: 결정적인 차이점

javascript
// ❌ 표준 Playwright 방식: 비어 있는 새 크롬 창을 생성합니다.
const browser = await chromium.launch();

// ✅ Mbbrowser Playwright 방식: 이미 존재하는 핑거프린트 환경의 제어권을 가져옵니다.
const browser = await chromium.connectOverCDP(wsEndpoint);
비교 항목표준 launch()Mbbrowser connectOverCDP()
브라우저 상태완전히 새로운 빈 상태핑거프린트, 프록시, 쿠키가 모두 적용됨
결과대상 사이트에서 일반 크롬 봇으로 인식대상 사이트에서 "실제 사용자"로 인식
다계정 관리구분 불가능Session_ID를 통해 정확하게 매칭됨

data.http 대신 data.ws를 사용하나요?

필드예시 형식적합한 프레임워크
data.http127.0.0.1:9222Selenium (debuggerAddress)
data.wsws://127.0.0.1:9222/devtools/browser/xxxPlaywright / Puppeteer

Playwright의 connectOverCDP는 전체 ws://... 주소를 필요로 합니다.

browser.contexts()[0]: 새 컨텍스트를 생성하지 마세요

javascript
// ❌ 틀린 방식: 새 컨텍스트를 생성하면 Mbbrowser에 저장된 쿠키와 저장소가 무시됩니다.
const context = await browser.newContext();

// ✅ 옳은 방식: Mbbrowser의 기존 컨텍스트를 사용합니다 (계정 상태 보존).
const context = browser.contexts()[0];

문제 해결 (Troubleshooting)

❓ 오류: connect ECONNREFUSED 127.0.0.1:8186

ApiServer가 시작되지 않았거나 포트가 틀렸습니다. apiserver.exe 터미널 창이 실행 중인지 확인하세요.

❓ 오류: Browser closed 또는 Target page, context or browser has been closed

Mbbrowser 환경이 닫혔습니다 (시간 초과 또는 수동 종료). /api/v1/browser/start를 다시 호출하세요.

browser.contexts()가 빈 배열을 반환하는 경우

환경이 처음 열릴 때 기본 컨텍스트가 초기화되는 데 잠시 시간이 걸릴 수 있습니다. 짧은 대기를 추가하세요.

javascript
// 컨텍스트가 나타날 때까지 대기 (최대 5초)
let context;
for (let i = 0; i < 50 && !browser.contexts().length; i++) {
  await new Promise(r => setTimeout(r, 100));
}
context = browser.contexts()[0];

browser.close()를 호출하면 Mbbrowser 창이 닫히나요?

connectOverCDP 모드에서 browser.close()는 Playwright 연결만 끊으며, Mbbrowser 창 자체를 닫지는 않습니다. 창을 닫으려면 정지(Stop) 인터페이스를 호출해야 합니다.

javascript
await axios.post(`${API_URL}/api/v1/browser/stop`, { Session_ID: SESSION_ID });

TIP

코딩할 준비가 되셨나요? 다음 장 핵심 API 레퍼런스에서 Playwright의 강력한 Locator 및 Page API 사용법을 배웁니다.