Skip to main content
Summary

왜 브라우저 자동화가 필요한가

실무에는 API가 없는 시스템이 많다. 오래된 관리자 페이지, 협력사 포털, 공공기관 사이트, 배송 조회 화면, 정산 파일 다운로드 페이지가 대표적이다. 담당자는 매일 같은 화면에 로그인하고, 같은 조건을 입력하고, 결과 파일을 내려받는다. 이 일은 복잡한 판단보다 반복 클릭과 입력이 많다.

브라우저 자동화는 이런 업무를 파이썬으로 실행하는 방식이다. 사람이 하던 클릭, 입력, 검색, 다운로드를 프로그램이 대신한다. 다만 브라우저 자동화는 첫 번째 선택지가 아니라 마지막 선택지에 가깝다. 가능하면 API 연동을 먼저 검토해야 한다.

API는 화면 모양이 바뀌어도 비교적 안정적으로 동작한다. 데이터도 구조화되어 있어 오류를 확인하기 쉽다. 반면 브라우저 자동화는 화면 버튼 이름, HTML 구조, 로딩 속도에 영향을 많이 받는다. 버튼 위치나 문구가 바뀌면 어제 되던 자동화가 오늘 멈출 수 있다.

따라서 판단 순서는 이렇게 잡는다.

  1. 공식 API가 있는지 확인한다.

  2. CSV, 엑셀, SFTP 같은 대체 데이터 제공 방식이 있는지 확인한다.

  3. 관리자 페이지에서 반복 작업만 가능한지 확인한다.

  4. 법무·보안·시스템 담당자의 승인을 받은 뒤 브라우저 자동화를 적용한다.

브라우저 자동화는 "API가 없으니 몰래 접근한다"가 아니다. 사람이 권한을 가지고 합법적으로 하던 반복 업무를, 승인된 범위 안에서 안전하게 줄이는 방법이다.

웹 업무와 브라우저 작업 자동화하기AI 생성 이미지

무엇을 자동화할 수 있는가

브라우저 자동화로 자주 처리하는 업무는 다음과 같다.

  • 관리자 페이지 로그인 후 주문 상태 검색

  • 협력사 포털에서 월별 정산 파일 다운로드

  • 고객 ID를 입력해 처리 상태 확인

  • 내부 시스템에 엑셀 데이터를 한 건씩 입력

  • 웹 화면의 표 데이터를 수집해 데이터베이스에 저장

  • 처리 완료 후 증빙 화면을 캡처해 보관

예를 들어 매일 아침 담당자가 협력사 포털 5곳에 접속해 전날 주문 파일을 다운로드한다고 하자. API가 없다면 자동화 흐름은 다음처럼 설계할 수 있다.

  1. config.json에서 사이트 주소와 다운로드 조건을 읽는다.

  2. 환경 변수에서 계정 정보를 불러온다.

  3. 브라우저를 실행하고 로그인한다.

  4. 날짜 조건을 입력하고 검색한다.

  5. 파일을 다운로드한다.

  6. 파일명을 partner_2026-05-27.xlsx처럼 표준화한다.

  7. 다운로드 성공 여부를 로그에 남긴다.

  8. 실패한 사이트만 담당자에게 알린다.

여기서 중요한 점은 "화면을 조작하는 코드"보다 "업무 결과를 검증하는 구조"다. 파일이 실제로 저장되었는지, 파일 크기가 0이 아닌지, 이미 받은 파일을 다시 받은 것은 아닌지, 어느 계정으로 언제 실행했는지 기록해야 한다.

Playwright와 Selenium의 역할

파이썬에서 브라우저 자동화에 자주 쓰는 도구는 Playwright와 Selenium이다. 둘 다 브라우저를 열고, 페이지로 이동하고, 요소를 찾아 클릭하거나 입력할 수 있다.

Selenium은 오래된 도구다. 자료가 많고 기업 환경에서 이미 사용 중인 경우가 많다. 기존 테스트 자동화나 레거시 시스템과 맞추기 좋다. 대신 브라우저 드라이버 설정, 명시적 대기, 버전 호환 문제를 더 신경 써야 할 때가 있다.

Playwright는 비교적 현대적인 웹 앱 자동화에 강하다. React, Vue 같은 자바스크립트 기반 화면에서는 버튼이 보이는 순간, 클릭 가능한 순간을 자동으로 기다려 주는 기능이 있어 코드가 간결해지는 경우가 많다.1 다운로드, 새 창, 여러 브라우저 컨텍스트 처리도 실무 자동화에 잘 맞는다.2

선택 기준은 단순하다.

  • 이미 조직에서 Selenium을 쓰고 있다면 Selenium으로 시작한다.

  • 새 프로젝트이고 동적인 웹 화면이 많다면 Playwright를 우선 검토한다.

  • 오래된 내부 시스템이거나 특정 브라우저 호환성이 중요하면 Selenium이 편할 수 있다.

  • 유지보수 담당자가 익숙한 도구를 선택한다.

도구보다 중요한 것은 화면 자동화를 작은 함수로 나누고, 실패했을 때 원인을 남기는 것이다.

Playwright로 로그인과 다운로드 자동화하기

다음 예시는 Playwright로 관리자 페이지에 로그인한 뒤 파일을 다운로드하는 기본 구조다. 실제 사이트마다 버튼 이름과 입력 칸 이름은 다르므로 그대로 실행하기보다 흐름을 이해하는 용도로 보자.

from pathlib import Path
from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeoutError

DOWNLOAD_DIR = Path("output/downloads")
DOWNLOAD_DIR.mkdir(parents=True, exist_ok=True)


def login(page, config):
    page.goto(config["login_url"])
    page.get_by_label("Email").fill(config["email"])
    page.get_by_label("Password").fill(config["password"])
    page.get_by_role("button", name="Login").click()
    page.wait_for_url("**/dashboard", timeout=15000)


def download_report(page, report_date):
    page.get_by_role("link", name="Reports").click()
    page.get_by_label("Date").fill(report_date)
    page.get_by_role("button", name="Search").click()

    with page.expect_download() as download_info:
        page.get_by_role("button", name="Download Excel").click()

    download = download_info.value
    save_path = DOWNLOAD_DIR / f"report_{report_date}.xlsx"
    download.save_as(save_path)
    return save_path


def main(config, report_date):
    try:
        with sync_playwright() as p:
            browser = p.chromium.launch(headless=True)
            context = browser.new_context(accept_downloads=True)
            page = context.new_page()

            login(page, config)
            file_path = download_report(page, report_date)
            print(f"다운로드 완료: {file_path}")

            browser.close()
    except PlaywrightTimeoutError as e:
        print(f"화면 로딩 지연 또는 요소 탐색 실패: {e}")

이 코드에서 눈여겨볼 부분은 세 가지다.

첫째, 계정 정보는 코드에 직접 쓰지 않아야 한다. 예시에서는 config로 표현했지만, 실제 운영에서는 비밀번호를 환경 변수나 비밀 관리 도구에서 읽어야 한다.

둘째, login()과 download_report()를 분리했다. 자동화가 커질수록 한 함수에 모든 클릭을 몰아넣으면 유지보수가 어렵다. 화면 단위, 업무 단계 단위로 나누는 것이 좋다.

셋째, 다운로드 파일명을 업무 기준으로 다시 저장했다. 브라우저가 내려받는 원래 파일명은 download.xlsx처럼 의미가 없을 수 있다. 자동화 결과물은 날짜, 거래처, 시스템명을 포함해 나중에 추적할 수 있어야 한다.

Selenium으로 입력 화면 자동화하기

Selenium은 명시적 대기를 잘 쓰는 것이 중요하다. 화면이 아직 준비되지 않았는데 바로 클릭하면 오류가 난다. time.sleep(5)처럼 무조건 기다리는 방식은 느리고 불안정하다. 대신 특정 버튼이 클릭 가능한 상태가 될 때까지 기다리는 편이 낫다.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def update_status(driver, order_id, new_status):
    wait = WebDriverWait(driver, 15)

    search_box = wait.until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, "input[name='orderId']"))
    )
    search_box.clear()
    search_box.send_keys(order_id)

    wait.until(
        EC.element_to_be_clickable((By.CSS_SELECTOR, "button.search"))
    ).click()

    status_select = wait.until(
        EC.element_to_be_clickable((By.CSS_SELECTOR, "select[name='status']"))
    )
    status_select.send_keys(new_status)

    wait.until(
        EC.element_to_be_clickable((By.CSS_SELECTOR, "button.save"))
    ).click()

이런 입력 자동화는 특히 조심해야 한다. 다운로드는 실패해도 다시 받을 수 있지만, 상태 변경이나 저장 버튼 클릭은 실제 업무 데이터를 바꾼다. 따라서 처음에는 반드시 테스트 모드나 검증 계정에서 실행해야 한다. 운영 반영 전에는 "몇 건을 어떤 값으로 바꿀지" 미리 목록으로 출력하고 담당자가 승인하도록 설계한다.

브라우저 자동화에서 자주 생기는 문제

브라우저 자동화는 화면에 의존한다. 그래서 다음 문제가 자주 발생한다.

화면 변경

버튼 이름이 Download에서 Export로 바뀌면 자동화가 멈출 수 있다. HTML 구조가 바뀌어도 같은 문제가 생긴다. 가능하면 개발팀에 요청해 주요 버튼에 data-testid 같은 안정적인 식별자를 넣는 것이 좋다. 어렵다면 CSS 선택자보다 역할, 라벨, 표시 텍스트처럼 사람이 이해하기 쉬운 기준을 우선 사용한다.

실패 시에는 스크린샷을 저장하면 원인 파악이 빠르다.

page.screenshot(path="logs/failure_order_page.png", full_page=True)

로딩 지연

웹 페이지는 네트워크 상황과 서버 상태에 따라 늦게 뜰 수 있다. 이때 무작정 짧은 시간 안에 요소를 찾으면 실패한다. Playwright의 자동 대기나 Selenium의 명시적 대기를 사용하고, 업무상 허용 가능한 타임아웃을 정한다. 반복 실패하면 무한 재시도하지 말고 중단 후 알림을 보내야 한다.

캡차와 다중 인증

캡차는 자동화를 막기 위한 장치다. 이를 우회하려고 하면 법적·보안 문제가 생길 수 있다. 다중 인증도 마찬가지다. 해결책은 우회가 아니라 공식 API 요청, 서비스 계정 발급, IP 허용 목록, 관리자 승인 절차 같은 정식 방법이어야 한다.

부득이하게 사람이 한 번 인증해야 한다면, 자동화가 로그인 화면까지만 열고 담당자가 인증한 뒤 다음 단계를 진행하도록 설계할 수 있다. 이 경우에도 세션 저장 방식, 계정 공유 여부, 접근 로그를 보안 담당자와 검토해야 한다.

세션 만료

오래 실행되는 자동화는 중간에 로그아웃될 수 있다. 이때 저장 버튼을 눌렀다고 생각했지만 실제로는 로그인 페이지로 이동했을 수 있다. 중요한 작업 전후에는 현재 URL, 로그인 사용자 표시, 성공 메시지를 확인해야 한다.

예를 들어 저장 후에는 "처리되었습니다" 메시지나 변경된 상태 값을 다시 조회해 검증한다. 클릭이 곧 성공은 아니다.

웹 스크래핑은 더 엄격하게 다룬다

브라우저 자동화가 내부 업무 화면을 조작하는 것이라면, 웹 스크래핑은 웹 페이지에서 데이터를 수집하는 작업이다. 둘은 기술적으로 비슷하지만 위험은 다르다. 특히 외부 웹사이트에서 데이터를 수집할 때는 서비스 약관, robots.txt, 접근 권한, 개인정보, 저작권, 서버 부하를 확인해야 한다.3

다음 질문에 답하지 못하면 자동화를 시작하지 않는 것이 좋다.

  • 이 사이트의 약관은 자동 수집을 허용하는가?

  • 로그인 후 볼 수 있는 데이터를 수집할 권한이 우리에게 있는가?

  • 수집 대상에 개인정보나 민감정보가 포함되는가?

  • 수집 빈도가 상대 서버에 부담을 주지 않는가?

  • 수집한 데이터를 어디에 저장하고 언제 삭제하는가?

  • 이 자동화에 대해 업무 책임자와 보안 담당자의 승인을 받았는가?

스크래핑은 "기술적으로 가능하다"와 "업무적으로 해도 된다"가 다르다. 자동화는 접근 통제를 우회하거나, 유료 데이터를 무단 복제하거나, 서비스에 과도한 요청을 보내는 방식으로 사용하면 안 된다. 브라우저 자동화는 사람의 행동을 빠르게 반복할 수 있으므로, 잘못 설계하면 대상 서비스에 부하를 주거나 민감한 데이터를 대량으로 노출시킬 수 있다.4

AI는 어디에 붙일 수 있는가

브라우저 자동화 자체는 규칙 기반으로 설계하는 것이 안정적이다. 어느 페이지로 가고, 어떤 버튼을 누르고, 어떤 파일을 받을지는 명확한 절차다. 여기에 AI를 무리하게 넣으면 예측하기 어려운 행동이 생길 수 있다.

AI가 유용한 지점은 브라우저 조작 이후다.

  • 내려받은 공지사항 PDF 요약

  • 웹 화면에서 수집한 고객 문의 문장 분류

  • 상품 설명 텍스트에서 주요 속성 추출

  • 오류 메시지를 사람이 읽기 쉬운 형태로 정리

반대로 저장 버튼 클릭, 결제 승인, 주문 취소, 계정 권한 변경 같은 작업은 AI 판단만으로 실행하지 않는다. 규칙 기반 조건과 사람의 승인 단계를 둔다.

운영 가능한 브라우저 자동화 체크리스트

브라우저 자동화는 개인 PC에서 한 번 성공했다고 끝이 아니다. 반복 운영하려면 다음 항목을 확인해야 한다.

  • 계정과 비밀번호를 코드에 저장하지 않는다.

  • 테스트 환경 또는 테스트 계정에서 먼저 검증한다.

  • 실행 전 처리 대상 목록을 만든다.

  • 변경 작업은 승인 후 실행한다.

  • 실행 결과, 실패 사유, 스크린샷을 로그로 남긴다.

  • 다운로드 파일명과 저장 경로를 표준화한다.

  • 중복 실행을 막기 위해 처리 이력을 저장한다.

  • 화면 변경에 대비해 담당자를 정한다.

  • 캡차나 접근 제한을 우회하지 않는다.

  • 외부 사이트는 약관과 수집 권한을 확인한다.

브라우저 자동화는 API가 없는 업무를 자동화할 수 있는 현실적인 대안이다. 하지만 화면에 의존하기 때문에 깨지기 쉽고, 실제 데이터를 바꿀 수 있기 때문에 위험도 있다. 안정적인 자동화는 빠른 클릭 코드가 아니라 승인, 검증, 로그, 예외 처리를 포함한 운영 구조에서 나온다.

참고

1Playwright vs Selenium: Which Automation Tool Should You Use in 2026?

2Playwright vs. Selenium: Which Is Better for Web Scraping?

3Browser Automation & Legal Compliance

4Browser Automation: Revolutionizing Digital Interactions

책 목록

파이썬과 AI를 활용한 비즈니스 자동화

전체 목차 보기

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

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

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

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

참여하기