3단계

"3단계 진행해 보자."

Intro

좋습니다! 이제 3단계: Selenium + Headless 브라우저 환경 구성으로 넘어가겠습니다. 이 단계에서는 실제 웹 브라우저를 Docker 컨테이너 안에서 Headless 모드로 실행하여, JavaScript까지 렌더링되는 웹페이지를 제어하는 환경을 구성할 거예요.

✅ 3단계 목표 요약

목표 내용
Selenium 환경 구성 selenium/standalone-chrome Docker 이미지 사용
NAS Python 코드에서 원격으로 Selenium 제어 RemoteWebDriver로 연결
JavaScript 렌더링되는 웹페이지 크롤링 테스트 Google, YouTube, 동적 페이지 등 실습 가능

🧱 구성 아키텍처

NAS (Python 코드)  
   ⇅ (HTTP:4444)
Docker 컨테이너 (Selenium + Chrome Headless)

✅ Step-by-Step 실행

📥 1. Selenium Docker 이미지 다운로드

sudo docker pull selenium/standalone-chrome

이 이미지는 Chrome + WebDriver + VNC 서버가 모두 포함된 풀 패키지입니다.

🚀 2. Selenium 컨테이너 실행

sudo docker run -d --name selenium-chrome \
  -p 4444:4444 \
  selenium/standalone-chrome
  • 4444 포트는 WebDriver와 통신하는 포트입니다.
  • 컨테이너가 실행되면 Selenium Grid 서버가 열립니다.

상태 확인: http://<NAS_IP>:4444/status

🧪 3. NAS에서 Python 스크립트 작성 (selenium-test.py)

# selenium-test.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

options = Options()
options.add_argument("--headless")  # 창 없이 실행
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")

driver = webdriver.Remote(
    command_executor="http://<NAS_IP>:4444/wd/hub",
    options=options
)

driver.get("https://example.com")
print("Page title:", driver.title)
driver.quit()

반드시 <NAS_IP>를 실제 IP 주소로 바꿔주세요 (예: 192.168.0.201)

▶ 4. Python 실행 환경에서 테스트

sudo docker run -it --rm \
  -v /volume1/docker-scripts:/app \
  python:3.10 bash

컨테이너 내부에서:

cd /app
pip install selenium
python selenium-test.py

✅ 결과 기대 출력

Page title: Example Domain

→ 브라우저가 실제로 열리진 않지만 Headless Chrome이 해당 페이지를 받아서 제목을 출력한 것입니다. => 저자의 DNS에서는 example.com이 resolve되지 않았지만, chrome browser에서는 DNS over HTTPS (DoH) 또는 DNS over TLS (DoT) 사용 혹은 로컬 OS DNS 설정 무시하고 자체적으로 구글/클라우드플레어 등의 DNS를 사용할 수 있다고 한다.

📌 다음 가능 실습

  • 특정 요소 추출: driver.find_element(By.ID, "some-id")
  • 스크린샷 저장: driver.save_screenshot("page.png")
  • YouTube 같은 SPA(Single Page App) 페이지 분석

지금 실행해보시고, 잘 되면 4단계로 자동화 및 로그 저장으로 넘어가볼게요!
진행 중 오류가 있으면 어떤 메시지 나왔는지 공유해주시면 바로 도와드릴게요.

4 단계

"4단계 진행해 보자."

Intro

좋습니다! 이제 4단계: NAS 내부에서 Python 코드와 Selenium 컨테이너 연동 자동화로 넘어가겠습니다.

이 단계는 지금까지 구성한 환경을 실제 자동화 스크립트 형태로 정리하고,

  • NAS 공유 폴더에 코드/결과를 저장하고
  • 여러 번 실행해도 안정적으로 동작하도록 구성하는 것을 목표로 합니다.

✅ 4단계 목표 요약

항목 설명
Python 코드 자동 실행 크론탭이나 수동 실행이 가능한 형태로 구성
컨테이너 상태 자동 체크 Selenium 서버가 떠 있는지 확인
결과 저장 크롤링 결과 또는 스크린샷을 NAS에 저장
에러 시 재시도 또는 로그 저장 나중에 디버깅을 위해 남겨두기

✅ Step-by-Step

📁 1. NAS 공유 폴더 구조 설정 (예: /volume1/docker-scripts)

/volume1/docker-scripts/ -> 내환경은 /volume2/backups/scripts/
├── selenium-test.py
├── output/
│   ├── last_result.txt
│   └── page_screenshot.png
└── logs/
    └── run.log

필요한 하위 디렉토리를 미리 만들어주세요.

🐍 2. selenium-test.py 업데이트 (자동화 + 저장)

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time
import os
from datetime import datetime

# 설정
NAS_OUTPUT_DIR = "/app/output"
NAS_LOG_DIR = "/app/logs"
URL = "https://example.com"

# 로그 기록
def log(message):
    timestamp = datetime.now().strftime("[%Y-%m-%d %H:%M:%S]")
    with open(os.path.join(NAS_LOG_DIR, "run.log"), "a") as f:
        f.write(f"{timestamp} {message}\n")
    print(f"{timestamp} {message}")

try:
    log("Starting browser...")

    options = Options()
    options.add_argument("--headless")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")

    driver = webdriver.Remote(
        command_executor="http://<NAS_IP>:4444/wd/hub",  # 실제 NAS IP 입력
        options=options
    )

    driver.get(URL)
    log(f"Accessed: {URL}")

    # 저장: 제목과 스크린샷
    title = driver.title
    with open(os.path.join(NAS_OUTPUT_DIR, "last_result.txt"), "w") as f:
        f.write(f"Page Title: {title}\n")

    screenshot_path = os.path.join(NAS_OUTPUT_DIR, "page_screenshot.png")
    driver.save_screenshot(screenshot_path)
    log(f"Saved screenshot to: {screenshot_path}")

    driver.quit()
    log("Browser closed.")

except Exception as e:
    log(f"ERROR: {e}")

🔁 <NAS_IP>는 반드시 실제 IP로 대체해주세요.
📁 /app/output, /app/logs는 Docker에서 마운트할 NAS 공유 폴더입니다.

🐳 3. Python 컨테이너에서 실행

sudo docker run -it --rm \
  -v /volume1/docker-scripts:/app \
  python:3.10 bash

컨테이너 내부에서:

cd /app
pip install selenium
python selenium-test.py

✅ 결과 확인

  • output/last_result.txt: 페이지 제목
  • output/page_screenshot.png: 렌더링된 스크린샷
  • logs/run.log: 실행 로그 기록

page_screenshot.png

🔄 자동 실행 팁 (선택)

추후 cron 또는 Synology의 작업 스케줄러(Task Scheduler) 를 이용해서 아래 명령을 정기적으로 실행 가능:

sudo docker run --rm \
  -v /volume1/docker-scripts:/app \
  python:3.10 python /app/selenium-test.py

셸 스크립트로 저장해두면 더 편리합니다

✅ 다음 단계로 준비되셨다면…

  • Selenium 대신 Playwright, Pyppeteer 등 대안 브라우저 사용
  • Selenium 컨테이너에서 Python까지 통합 실행
  • Docker Compose로 Selenium + Python 함께 구성 (5단계)

지금 자동화된 스크립트 실행해보시고, outputlogs에 결과 잘 남는지 확인해 보세요!
오류나 디테일 조정 원하시면 언제든지 도와드릴게요.

추가 단계

"자동 실행의 예에서는 selenium package 설치가 안되어 있어서 실패 할 것 같은데. 어떻게 생각해?"

이를 기반으로 Dockfile을 통해서 docker image를 만드는 방법을 알게 되었다.

"selenium beautifulsoup4 requests openai 까지 포함하는 docker image를 만드는 Dockerfile을 제안해줘. python-webscrap이라는 이름의 이미지로 만들었으면해. 추후에 이 이미지를 이용해서 news website를 bs4 혹은 selenium으로 scrapping하고 openai로 요약하는 작업을 해보려해."

Intro

멋진 계획입니다! 요청하신 대로 다음과 같은 Python 패키지들이 포함된 Docker 이미지를 만들기 위한 Dockerfile을 아래에 제안드립니다:

  • selenium
  • beautifulsoup4
  • requests
  • openai

이미지 이름은 python-webscrap으로 빌드할 수 있도록 구성하겠습니다.

✅ Dockerfile: python-webscrap

# 1. Python 3.10 베이스 이미지 사용
FROM python:3.10

# 2. 필수 패키지 설치
RUN pip install --no-cache-dir \
    selenium \
    beautifulsoup4 \
    requests \
    openai

# 3. 작업 디렉토리 설정 (선택 사항)
WORKDIR /app

📄 파일 이름 예시: /volume1/docker-scripts/Dockerfile-webscrap

✅ 이미지 빌드 방법

cd /volume1/docker-scripts -> 내 환경에서는 /volume2/backups/scripts
sudo docker build -t python-webscrap -f Dockerfile-webscrap .

-f 옵션은 Dockerfile 파일명이 기본값(Dockerfile)이 아닌 경우에 사용

✅ 이미지 실행 예시

sudo docker run -it --rm \
  -v /volume2/backups/scripts:/app \
  python-webscrap bash

이 실행 파일은 내 환경에 맞추고 interactive한 환경에서 python 명령어들을 테스트할 수 있게 하였다. 이 때, selenium-test.py와 openai-test.py를 테스트 해볼 수 있다.

from openai import OpenAI
import os

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY") or "YOUR KEY")
prompt = f"한국어로 3 문장 생성해줘."
try:
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}]
    )
    print(response.choices[0].message.content.strip())
except Exception as e:
    print(f"(생성 실패: {e})")

 

+ Recent posts