이번 포스트에서는 SeleniumBase를 Docker 환경에서 안정적으로 실행하기 위한 이미지 빌드와 테스트 방법을 다루고, 이후에는 SerpApi로 전환한 이유와 사용법까지 실전 예제를 포함해 설명하겠습니다.
my-selenium-app/
├── Dockerfile
├── requirements.txt # (선택) Python 패키지 목록
└── test_search.py # 테스트 코드
requirements.txt 예시
seleniumbase==4.18.1
google-cloud-bigquery
google-cloud-storage
# Stage 1: Base
FROM python:3.11-slim as base
RUN apt-get update && apt-get install -y \
wget gnupg gnupg1 gnupg2 ca-certificates \
libnss3 libgconf-2-4 libappindicator3-1 fonts-liberation \
&& rm -rf /var/lib/apt/lists/*
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list \
&& apt-get update && apt-get install -y google-chrome-stable
# Stage 2: Dependencies
FROM base as deps
WORKDIR /app
RUN pip install --upgrade pip && pip install seleniumbase
# Stage 3: Final Application
FROM deps as final
WORKDIR /app
COPY . .
CMD ["python", "test_search.py"]
test_search.py 예시
import time
from seleniumbase import SB
from selenium.webdriver.common.keys import Keys
def search_keyword(keyword):
with SB(uc=True, test=True, locale="ko") as sb:
sb.open("https://www.google.com")
sb.type("input[name='q']", keyword)
sb.send_keys("input[name='q']", Keys.ENTER)
sb.sleep(2)
print(f"검색 완료: {keyword}")
def main():
keywords = ["example1", "example2", "example3", "example4"]
for kw in keywords:
search_keyword(kw)
time.sleep(1)
if __name__ == "__main__":
main()``````
docker build -t my-seleniumbase-image .
브라우저 없이 CLI 환경에서도 SeleniumBase 실행이 가능
구글 쇼핑 페이지에서 검색창(input[name='q'])이 로딩되지 않음
자바스크립트 기반 동적 로딩이 Cloud Run 환경에서는 완전히 동작하지 않음
검색 결과가 보이지 않거나 403/CAPTCHA로 막힘
이 문제로 인해 API 기반 접근이 가능한 SerpApi로 전환함.
- 안정성: 브라우저 없이 API로 직접 호출 가능 (Cloud Run에서 안정 작동)
- 구조화된 응답: JSON으로 랭킹, 링크, 판매처 등 추출 가능
- 순위 확인 가능: shopping_results 리스트 인덱스로 노출 순위 판단
from serpapi import GoogleSearch
from google.cloud import bigquery
from datetime import datetime, timedelta, timezone
client = bigquery.Client(project="my-gcp-project")
query = """
SELECT id, keyword FROM `my-gcp-project.my_dataset.mytable`
WHERE google_rank IS NULL
"""
keywords = [dict(row) for row in client.query(query).result()]
API_KEY = "your_serpapi_key"
for row in keywords:
params = {
"engine": "google_shopping",
"q": row["keyword"],
"hl": "ko",
"gl": "kr",
"api_key": API_KEY
}
search = GoogleSearch(params)
results = search.get_dict()
rank = 1000000
for i, item in enumerate(results.get("shopping_results", []), 1):
if row["id"] in item.get("title", "") and "louisvuitton.com" in item.get("source", ""):
rank = i
break
now_kst = datetime.now(timezone(timedelta(hours=9))).isoformat()
update_sql = f"""
UPDATE `my-gcp-project.my_dataset.mytable`
SET google_rank = {rank},
google_loadtime = TIMESTAMP("{now_kst}")
WHERE id = "{row['id']}" AND keyword = "{row['keyword']}"
"""
client.query(update_sql).result()
총 40개의 결과를 찾았습니다.
[1] example 제품 M12345 | 판매처: louisvuitton.com | 순위: 1
[2] ...
SeleniumBase는 로컬 테스트에 적합, 시각화도 가능하지만 Cloud 환경에선 불안정
SerpApi는 구조화된 결과, 안정적인 응답, 순위 판단이 가능한 API 기반이라 실제 배포에는 훨씬 유리
Docker 기반 개발 → 로컬 테스트 → Cloud Run 배포까지 모든 단계에서 활용 가능