Akashic Records

Selenium: 웹 자동화 및 자바스크립트 처리 본문

Web Crawling for Beginners

Selenium: 웹 자동화 및 자바스크립트 처리

Andrew's Akashic Records 2024. 5. 9. 10:29
728x90

Here's a digital artwork depicting a Python code on a computer screen using the Selenium library. The setting includes a modern office desk with elements typical of a programming environment. Feel free to take a closer look at the image above!

 

Selenium의 주요 특징

  1. 다양한 브라우저 지원: Selenium은 Chrome, Firefox, Safari, Edge 등 다양한 웹 브라우저를 지원합니다. 각 브라우저에 맞는 드라이버를 사용하여 자동화 작업을 수행할 수 있습니다.
  2. 언어 지원: Python, Java, C#, Ruby 등 여러 프로그래밍 언어를 지원하여, 개발자가 익숙한 언어로 스크립트를 작성할 수 있습니다.
  3. 실시간 사용자 상호작용 에뮬레이션: 사용자의 웹 브라우징 활동을 모방하여, 클릭, 스크롤, 텍스트 입력, 파일 업로드 등의 동작을 자동으로 수행할 수 있습니다.
  4. 요소 위치 지정: 웹 페이지 내의 요소를 찾기 위해 XPath, CSS 선택자 등을 사용할 수 있으며, 이를 통해 정확한 요소에 접근하고 조작할 수 있습니다.
  5. 동적 콘텐츠 처리: AJAX와 같은 기술로 생성된 동적 콘텐츠를 다룰 때 유용하며, 요소가 로드될 때까지 대기하고 이벤트를 트리거하는 기능을 제공합니다.

Selenium의 구성 요소

  • Selenium WebDriver: 실제 브라우저를 제어하며, 각 브라우저에 맞는 드라이버(ChromeDriver, GeckoDriver 등)를 통해 브라우저와 직접적으로 상호작용합니다.
  • Selenium Grid: 다양한 브라우저 환경에서 테스트를 병렬로 실행할 수 있도록 지원하는 도구입니다. 서로 다른 운영 체제와 브라우저 조합에서 테스트를 분산시켜 실행할 수 있습니다.
  • Selenium IDE: 브라우저 확장 기능으로, 사용자의 웹 브라우징을 기록하고, 이를 자동화 스크립트로 변환하는 데 도움을 주는 도구입니다.

간단한 사용예시

Selenium의 최신 버전을 사용하여 Python에서 간단한 웹 크롤링 예제를 작성해 보겠습니다. 이 예제에서는 Chrome 브라우저를 사용하며, Selenium WebDriver를 통해 Google의 홈페이지를 열고, 검색어를 입력한 후 결과 페이지의 타이틀을 출력하는 스크립트입니다.

 

필요 조건

  • Python 설치
  • 패키지 설치 (pip install selenium webdriver_manager)

예제 코드

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

# Chrome WebDriver 초기화
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)

try:
    # Google 홈페이지 열기
    driver.get('https://www.google.com')

    # 검색창 찾기 (name 속성을 사용)
    search_box = driver.find_element(By.NAME, 'q')

    # 검색창에 "Selenium" 입력 후 엔터
    search_box.send_keys('Selenium' + Keys.ENTER)

    # 페이지 로딩 대기 (실제 사용시 적절한 대기 로직 필요)
    driver.implicitly_wait(5)

    # 결과 페이지의 타이틀 출력
    print(driver.title)

finally:
    # 브라우저 종료
    driver.quit()

 

코드 설명

  1. ChromeDriverManager: WebDriver를 자동으로 다운로드하고 경로를 설정하는 webdriver_manager 라이브러리를 사용하였습니다. 이를 사용하면 ChromeDriver의 경로를 수동으로 설정할 필요가 없습니다.
  2. webdriver.Chrome: WebDriver 인스턴스를 생성합니다.
  3. driver.get: 지정된 URL로 브라우저를 이동합니다.
  4. find_element: 페이지에서 요소를 찾습니다. 이 예제에서는 검색창을 name='q' 속성을 사용하여 찾습니다.
  5. send_keys: 키보드 입력을 시뮬레이션합니다. 검색어를 입력하고 Keys.ENTER를 보내어 검색을 실행합니다.
  6. implicitly_wait: 요소가 로드될 때까지 최대 지정된 시간(초) 동안 대기합니다.
  7. print(driver.title): 현재 페이지의 타이틀을 출력합니다.
  8. driver.quit: 모든 브라우저 창을 닫고 WebDriver 세션을 종료합니다.

이 스크립트는 Google 검색 페이지를 사용하여 기본적인 검색을 수행하고 결과 페이지의 타이틀을 콘솔에 출력하는 간단한 예입니다. 실제로는 더 복잡한 로직이나 추가적인 에러 핸들링이 필요할 수 있습니다.

 

주요기능 예시

Selenium의 사용법은 웹 자동화 및 테스팅 프로세스에서 복잡한 시나리오를 처리하는 방법을 포함합니다. 이러한 기능은 크롤링의 효율성을 높이고, 더 동적인 웹 사이트에서도 정확하게 데이터를 추출하거나, 사용자 상호작용을 시뮬레이션하는 데 도움을 줄 수 있습니다. 여기 몇 가지 다른 기능을 소개합니다:

 

1. 헤드리스 브라우저 사용하기

헤드리스 모드는 GUI 없이 브라우저를 실행하는 모드입니다. 이는 서버나 배치 파일에서 자동화된 테스트를 수행할 때 유용하며, GUI 로드에 필요한 리소스를 절약할 수 있습니다.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--headless")  # 헤드리스 모드 활성화

driver = webdriver.Chrome(options=chrome_options)
driver.get("https://example.com")
print(driver.title)
driver.quit()

 

2. 웹 요소에 대한 복잡한 상호작용

드래그 앤 드롭이나 키보드 조합과 같은 복잡한 사용자 상호작용을 구현할 수 있습니다.

from selenium.webdriver import ActionChains

driver.get("http://example.com")
element = driver.find_element(By.ID, "source")
target = driver.find_element(By.ID, "target")

actions = ActionChains(driver)
actions.drag_and_drop(element, target).perform()  # 드래그 앤 드롭 실행

3. 쿠키 다루기

Selenium을 사용하면 쿠키를 쉽게 추가하거나 삭제할 수 있습니다. 이는 로그인 세션을 유지하는 데 유용합니다.

# 쿠키 추가
driver.get("https://example.com")
driver.add_cookie({"name": "key", "value": "value"})

# 모든 쿠키 조회
cookies = driver.get_cookies()
print(cookies)

# 쿠키 삭제
driver.delete_cookie("key")
driver.delete_all_cookies()  # 모든 쿠키 삭제

 

4. 프록시 서버 사용

특정 테스트에서 IP 주소를 숨기거나, 지역적 제한을 우회하기 위해 프록시 서버를 설정할 수 있습니다.

from selenium.webdriver.common.proxy import Proxy, ProxyType

proxy_ip_port = 'ip:port'
proxy = Proxy({
    'proxyType': ProxyType.MANUAL,
    'httpProxy': proxy_ip_port,
    'ftpProxy': proxy_ip_port,
    'sslProxy': proxy_ip_port,
    'noProxy': ''  # 프록시를 사용하지 않을 주소들
})

capabilities = webdriver.DesiredCapabilities.CHROME
proxy.add_to_capabilities(capabilities)

driver = webdriver.Chrome(desired_capabilities=capabilities)

 

5. 스크린샷 찍기

테스트 중에 발생하는 문제를 진단하기 위해 특정 시점에서 스크린샷을 찍을 수 있습니다.

driver.get("https://example.com")
driver.save_screenshot('screenshot.png')

 

 

6. HTML 저장하기

테스트 중에 발생하는 문제를 진단하거나 데이터 분석을 위해 현재 페이지를 저장할 수 있습니다.

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

def save_webpage_source(url, filename='page_source.html'):

    options = Options()
    options.add_argument("--headless")
    driver = webdriver.Chrome(options=options)

    # 주어진 URL로 이동
    driver.get(url)

    # 사용자 ID와 비밀번호 입력
    user_id_input = driver.find_element(By.ID, "userId")
    password_input = driver.find_element(By.ID, "passwd")

    user_id_input.send_keys("admin")  # 사용자 ID 입력
    password_input.send_keys("1234")  # 비밀번호 입력

    # 로그인 함수 호출
    login_button = driver.find_element(By.XPATH,"/html/body/table/tbody/tr[3]/td/button[1]")
    login_button.click()

    # 로그인 후 변경 사항이 반영되기를 기다림
    time.sleep(3)  # 3초 대기

    user_mng_tag = driver.find_element(By.ID, "operations-tag-AuthenticationController")
    print(f"usermng tag {user_mng_tag.text}")

    # 페이지 소스 가져오기
    page_source = driver.page_source

    # 페이지 소스를 파일로 저장
    with open(filename, 'w', encoding='utf-8') as file:
        file.write(page_source)

    # 드라이버 종료
    driver.quit()
    print(f"Page source of {url} has been saved to {filename}")


# 사용 예시
if __name__ == "__main__":
    target_url = 'http:/xxxx.com/login'
    save_webpage_source(target_url, 'example_source.html')

 

implicitly_wait와 time.sleep

implicitly_waittime.sleep은 Selenium에서 웹 페이지의 요소와 상호 작용할 때 사용되는 두 가지 대기 방법이며, 각각 다른 상황과 요구 사항에 적합합니다.

 

1. implicitly_wait

  • 정의: implicitly_wait는 Selenium WebDriver에게 최대 특정 시간만큼 (예: 10초) 웹 요소가 나타날 때까지 기다리라고 지시합니다. 이 시간 동안 Selenium은 주어진 요소가 DOM에 나타날 때까지 주기적으로 요소를 찾습니다. 요소가 발견되면 즉시 다음 코드로 진행합니다.
  • 사용: 페이지 로딩 중 동적으로 나타나는 요소들을 기다릴 때 사용합니다. 예를 들어, 페이지가 완전히 로드된 후 요소가 동적으로 생성되는 경우, 이 요소가 나타날 때까지 WebDriver가 기다리게 할 수 있습니다.
  • 장점: 실제 요소가 사용 가능해지는 즉시 실행을 계속하기 때문에 불필요한 지연이 감소합니다.
  • 단점: 전역적으로 적용되므로, 한 번 설정하면 드라이버 세션의 모든 요소 탐색에 영향을 미칩니다. 때로는 예상보다 긴 대기 시간이 발생할 수 있습니다.

2. time.sleep

  • 정의: Python의 표준 라이브러리에 있는 time.sleep 함수는 지정된 시간(초) 동안 프로그램 실행을 정지합니다.
  • 사용: 특정 이벤트 후에 일정 시간 동안 대기해야 할 때 사용합니다. 예를 들어, 특정 스크립트 실행 후 UI가 업데이트되기를 기다릴 필요가 있을 때 유용합니다.
  • 장점: 매우 간단하고, 사용하기 쉽습니다. 지정된 시간 동안 무조건 대기하므로 예측 가능합니다.
  • 단점: 요소가 이미 로드되어 있어도 지정된 시간이 완료될 때까지 기다려야 하므로 비효율적일 수 있습니다. 시스템 리소스를 낭비하고 전체 테스트 시간을 불필요하게 늘릴 수 있습니다.

사용 시나리오 비교

  • implicitly_wait 사용 시나리오: 웹 페이지나 애플리케이션의 로딩 시간이 일정하지 않거나, 네트워크 속도의 영향을 받는 경우에 적합합니다. 페이지의 모든 요소가 로드될 때까지 기다리지 않고, 필요한 특정 요소가 로드되는 즉시 작업을 수행할 수 있습니다.
  • time.sleep 사용 시나리오: 테스트 중 일정 시간 간격을 두고 요소가 나타나길 기다릴 필요가 없는 경우, 또는 특정 프로세스가 완료되기를 일정 시간 동안 확실히 기다려야 할 때 사용합니다.

일반적으로, implicitly_wait은 Selenium 테스트에서 더 “스마트한” 대기 방법으로 권장되며, time.sleep은 그 사용을 최소화하는 것이 좋습니다. 이는 time.sleep이 프로세스 효율성을 저하시킬 수 있기 때문입니다.

728x90
Comments