Selenium의 일반적인 JavaScript 오류 이해 및 수정
웹 스크래핑을 할 때 셀레늄 웹드라이버, 특히 다음과 같은 동적 웹 요소를 처리할 때 JavaScript 관련 오류가 발생하는 것은 드문 일이 아닙니다. 섀도우 DOM. 개발자가 자주 직면하는 오류 중 하나는 JavascriptException: null 속성을 읽을 수 없습니다('shadowRoot' 읽기)., 이는 복잡한 페이지 요소와 상호작용할 때 자주 발생합니다.
이 오류는 일반적으로 Selenium이 내부 요소에 액세스하거나 상호 작용할 수 없을 때 발생합니다. 섀도우 DOM, 더 나은 모듈성을 위해 많은 현대 웹사이트에서 사용되는 독특한 유형의 캡슐화된 DOM 구조입니다. Python에서는 Selenium을 사용하여 브라우저를 제어하는 것이 이러한 요소로 인해 까다로울 수 있습니다.
Shopee와 같은 플랫폼의 웹 스크래핑 맥락에서 팝업이나 배너는 프로그래밍 방식으로 닫기 어려울 수 있는 Shadow DOM을 활용하는 경우가 많습니다. 이 문제는 자동화된 작업의 원활한 흐름을 방해하고 데이터 수집을 방해할 수 있습니다.
이 가이드는 다음 문제를 해결하기 위한 명확한 솔루션을 안내합니다. 'Null의 속성을 읽을 수 없습니다' 오류를 해결하고 다음을 사용하여 Shopee의 Shadow DOM에 포함된 팝업을 닫는 실용적인 접근 방식을 제공합니다. 파이썬 셀레늄.
명령 | 사용예 |
---|---|
shadowRoot | 이는 Shadow DOM 내의 요소에 액세스하는 데 사용됩니다. Shadow DOM은 기본 DOM 트리에서 특정 요소를 분리하므로 해당 요소에 액세스하려면 ShadowRoot 속성이 필요합니다. 이 스크립트에서는 팝업 내부에서 닫기 버튼을 찾는 데 사용됩니다. |
execute_script() | 이 Selenium 메소드를 사용하면 브라우저 세션 내에서 원시 JavaScript를 실행할 수 있습니다. 전통적인 Selenium 방법은 작동하지 않을 수 있으므로 Shadow DOM 요소와 상호 작용할 때 필수적입니다. |
WebDriverWait() | 이 명령은 Selenium에서 명시적 대기를 설정합니다. 요소를 클릭할 수 있게 되는 것과 같이 지정된 조건이 충족될 때까지 스크립트가 대기하도록 합니다. 이는 Shopee의 팝업에서 볼 수 있듯이 동적 콘텐츠 로딩에 중요합니다. |
expected_conditions | 이 모듈에는 요소 가시성 또는 존재 여부와 같이 WebDriverWait와 함께 사용할 수 있는 조건이 포함되어 있습니다. 클릭과 같은 작업은 대상 요소가 준비된 경우에만 발생합니다. |
EC.presence_of_element_located() | 대상 요소가 DOM에 존재하는지 확인하기 위해 WebDriverWait와 함께 사용되는 조건입니다. 이는 Shadow DOM의 요소가 로드되기를 기다릴 때 특히 유용합니다. |
EC.element_to_be_clickable() | WebDriverWait의 또 다른 유용한 조건은 상호 작용을 시도하기 전에 대상 요소가 표시되고 클릭 가능하도록 보장하여 동적 웹 페이지의 오류를 줄입니다. |
By.CSS_SELECTOR | 이 방법을 사용하면 CSS 선택기를 통해 요소를 찾을 수 있습니다. 이는 표준 XPath 방법을 사용하여 액세스할 수 없는 Shadow DOM 내부 요소를 대상으로 지정할 때 특히 유용합니다. |
driver.quit() | 스크립트 실행이 완료된 후 브라우저 인스턴스가 제대로 닫혔는지 확인합니다. 열려 있는 브라우저 세션을 떠나지 않는 것이 중요한 모범 사례입니다. |
Selenium 웹 스크래핑에서 Shadow DOM 및 팝업을 처리하는 방법
위에 제공된 스크립트는 다음을 사용하여 웹 스크래핑에서 발생하는 일반적인 문제를 해결하는 것을 목표로 합니다. 셀레늄 웹드라이버 Shadow DOM 요소와 상호작용할 때. Shadow DOM은 복잡한 웹 구성 요소에서 자주 사용되는 기본 DOM과 별도로 작동하는 웹 페이지의 일부입니다. Shopee와 같은 스크래핑 사이트의 경우 팝업이 Shadow DOM 내부에 자주 나타나며, 이는 기존 Selenium 방법으로 액세스할 경우 오류가 발생할 수 있습니다. 첫 번째 스크립트는 다음을 통해 JavaScript 실행을 사용하여 팝업을 닫도록 설계되었습니다. 실행_스크립트(), Selenium이 브라우저 컨텍스트 내에서 원시 JavaScript를 실행할 수 있게 해주는 강력한 도구입니다.
핵심 과제는 다음과 같은 일반적인 Selenium 명령을 사용하여 Shadow DOM 내부 요소에 액세스할 수 없다는 것입니다. find_element_by_xpath(). 대신에 우리는 JavaScript를 사용하여 Shadow DOM으로 이동합니다. 그림자 루트 재산. 스크립트는 먼저 섀도우 호스트 요소에 액세스한 다음 내부 구조를 쿼리하여 Shopee 팝업의 닫기 버튼을 대상으로 합니다. 활용하여 드라이버.실행_스크립트(), 스크립트는 이 격리된 DOM 내부의 요소를 조작하고 닫을 수 있습니다. 이 솔루션은 비동기적으로 로드되는 동적 페이지 요소를 처리하기 위해 명시적 대기와 결합될 때 잘 작동합니다.
두 번째 스크립트는 다음을 소개합니다. WebDriver잠깐만요, 동적 페이지 요소의 타이밍을 관리하기 위한 필수 도구입니다. Shopee의 팝업은 비동기식으로 로드되므로 이러한 요소와 직접 상호 작용하면 오류가 발생할 수 있습니다. 이를 방지하려면 웹드라이버기다림() 상호 작용하려는 요소가 완전히 로드되고 준비되었는지 확인합니다. 이 스크립트는 기본 DOM 요소와 섀도우 DOM 요소가 모두 존재할 때까지 기다립니다. 방법 EC.presence_of_element_location() Selenium은 요소가 표시되고 존재하는 후에만 요소와 상호 작용하도록 보장합니다. 이는 Null 참조 오류를 방지하는 데 중요합니다.
두 스크립트 모두에서 오류 상황을 다음과 같이 처리합니다. 시도 제외 요소를 찾을 수 없는 등 예상치 못한 오류로 인해 프로그램이 충돌하지 않도록 차단합니다. 오류 처리는 구조를 자주 업데이트하거나 팝업 동작을 변경하는 웹 사이트를 스크랩할 때 특히 중요합니다. 또한 이러한 스크립트는 다음을 사용하여 브라우저 세션을 종료하여 모범 사례를 따릅니다. 드라이버.종료() 메모리 누수나 성능 문제를 방지하기 위해 실행 후.
Python에서 Selenium을 사용하여 Shadow DOM 처리 및 팝업 닫기
Python을 Selenium WebDriver와 함께 사용하여 Shadow DOM 요소와 상호 작용하고 팝업을 동적으로 처리합니다.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import JavascriptException
import time
# Initialize WebDriver with Chrome
options = Options()
driver = webdriver.Chrome(service=Service(), options=options)
# Open Shopee website
driver.get('https://www.shopee.co.th/')
# Click the Thai language button
th_button = driver.find_element(By.XPATH, '/html/body/div[2]/div[1]/div[1]/div/div[3]/div[1]/button')
th_button.click()
# Pause to allow popups to load
time.sleep(3)
# Try to close the shadow DOM popup
try:
close_button = driver.execute_script('return document.querySelector("shopee-banner-popup-stateful")'
'.shadowRoot.querySelector("div.shopee-popup__close-btn")')
close_button.click()
except JavascriptException as e:
print("Error: ", e)
# Close the browser
driver.quit()
Shadow DOM 상호작용을 위해 WebDriverWait 사용
Selenium에서 명시적 대기를 사용하여 Shadow DOM 내의 요소가 상호 작용할 준비가 되었는지 확인합니다.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
# Initialize WebDriver with Chrome
options = Options()
driver = webdriver.Chrome(service=Service(), options=options)
# Open Shopee website
driver.get('https://www.shopee.co.th/')
# Click the Thai language button
th_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '/html/body/div[2]/div[1]/div[1]/div/div[3]/div[1]/button'))
)
th_button.click()
# Wait for the shadow DOM popup to be present
try:
shadow_host = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, 'shopee-banner-popup-stateful'))
)
shadow_root = driver.execute_script('return arguments[0].shadowRoot', shadow_host)
close_button = shadow_root.find_element(By.CSS_SELECTOR, 'div.shopee-popup__close-btn')
close_button.click()
except Exception as e:
print("Error closing the popup: ", e)
# Close the browser
driver.quit()
Selenium WebDriver로 동적 콘텐츠 처리
웹 스크래핑을 위해 Selenium WebDriver를 사용할 때 고려해야 할 또 다른 주요 측면은 처리 방법입니다. 동적 콘텐츠 페이지 로드 후 지속적으로 업데이트되거나 변경됩니다. Shopee와 같은 많은 최신 웹사이트에서는 JavaScript를 사용하여 콘텐츠를 동적으로 로드하고 업데이트합니다. 이는 페이지가 로드된 후 페이지의 요소를 즉시 사용하지 못할 수도 있음을 의미합니다. 이러한 경우 페이지 로드 이벤트를 기다리는 Selenium의 기본 동작만으로는 충분하지 않을 수 있습니다. 다음과 같은 명시적 대기 사용 WebDriver잠깐만요 특정 요소가 나타나거나 클릭 가능해질 때까지 기다리면 이 문제를 해결할 수 있습니다.
팝업, 배너 또는 복잡한 UI 구성 요소가 포함된 사이트를 스크랩하는 경우 섀도우 DOM, 그들과 상호작용하는 방법을 아는 것이 중요합니다. 이러한 구성 요소는 XPath 또는 CSS 선택기와 같은 기존 방법으로 액세스할 수 없는 격리된 DOM 구조 내의 요소를 숨깁니다. 사용하여 실행_스크립트() 명령은 브라우저 내에서 직접 JavaScript를 실행하고 Shadow DOM에 대한 액세스를 제공하며 페이지의 숨겨진 부분에 있는 닫기 버튼이나 양식 필드와 같은 요소와의 상호 작용을 허용함으로써 이러한 격차를 해소하는 데 도움이 됩니다.
또한 이러한 경우에는 오류 처리가 중요합니다. 웹사이트는 종종 구조를 변경하여 스크레이퍼가 손상될 수 있습니다. 올바른 사용 시도 제외 Python의 블록을 사용하면 다음과 같은 오류를 잡을 수 있습니다. 자바스크립트예외 스크레이퍼가 예기치 않게 충돌하지 않도록 우아하게 처리하십시오. 오류 세부 정보를 캡처하기 위해 로깅을 통합하면 근본 원인을 식별하고 향후 스크랩에서 문제를 해결하는 데 도움이 될 수 있습니다.
Selenium의 Shadow DOM 및 팝업 처리에 대해 자주 묻는 질문
- Shadow DOM은 무엇이며, 왜 액세스하기 어려운가요?
- 그만큼 shadow DOM 웹 개발자가 요소를 캡슐화하고 기본 문서의 스타일이나 스크립트의 영향을 받지 않도록 방지하는 데 사용하는 격리된 DOM 트리입니다. 전통적인 Selenium 메소드는 Shadow DOM 요소와의 직접적인 상호작용을 지원하지 않기 때문에 접근하기 어렵습니다.
- 어떻게 execute_script() Shadow DOM과 상호작용하는 데 도움이 되나요?
- execute_script() 브라우저 세션 내에서 JavaScript를 직접 실행하여 일반 Selenium 명령으로는 도달할 수 없는 Shadow DOM 요소에 액세스할 수 있습니다.
- 왜? WebDriverWait 동적 콘텐츠를 스크랩하는 데 중요합니까?
- WebDriverWait 스크립트는 요소와 상호작용하기 전에 클릭 가능하거나 존재하는 요소와 같은 특정 조건을 기다립니다. 이는 비동기적으로 로드되는 동적 콘텐츠를 처리하는 데 중요합니다.
- 마주쳤을 때 어떻게 해야 할까요? JavascriptException?
- JavascriptException JavaScript 코드 실행에 문제가 있을 때 발생합니다. 다음을 사용하여 오류 처리 구현 try-except 블록은 전체 스크립트를 충돌시키지 않고 이러한 오류를 포착하고 관리하는 데 도움이 됩니다.
- Shadow DOM을 사용하는 동적 팝업을 어떻게 닫을 수 있나요?
- Shadow DOM에 캡슐화된 동적 팝업을 닫으려면 먼저 다음을 사용하여 Shadow 루트에 액세스해야 합니다. execute_script() 그런 다음 Shadow DOM 내부에서 팝업 닫기 버튼을 찾습니다.
Selenium에서 Shadow DOM 처리에 대한 최종 생각
웹 스크래핑에 Selenium을 사용할 때 Shadow DOM 요소와 상호 작용하는 것이 어려울 수 있습니다. 그러나 JavaScript 실행과 명시적 대기를 활용하면 표준 메소드로는 접근하기 어려운 요소를 효과적으로 관리할 수 있습니다.
오류를 적절하게 처리하고 대기를 통합함으로써 스크래핑 스크립트가 강력하고 안정적인지 확인할 수 있습니다. 이러한 기술은 Shadow DOM에 포함된 동적 콘텐츠 및 팝업으로 작업할 때 흔히 발생하는 함정을 피하고 보다 원활한 스크래핑 환경을 보장하는 데 도움이 됩니다.
Selenium에서 Shadow DOM을 처리하는 데 유용한 소스 및 참조
- Selenium의 Shadow DOM 요소와의 상호작용에 대한 정보 Selenium WebDriver 문서 .
- JavascriptException 오류 처리에 대한 통찰력 스택 오버플로 .
- 다음을 사용하여 동적 콘텐츠를 웹 스크래핑하는 모범 사례에 대한 지침 실제 파이썬 .