Hiểu và sửa các lỗi JavaScript phổ biến trong Selenium
Khi quét web bằng Trình điều khiển web Selenium, việc gặp phải các lỗi liên quan đến JavaScript không phải là hiếm, đặc biệt khi xử lý các phần tử web động như bóng DOM. Một lỗi thường xuyên mà các nhà phát triển gặp phải là JavascriptException: Không thể đọc thuộc tính null (đọc 'shadowRoot'), điều này thường xảy ra khi tương tác với các phần tử trang phức tạp.
Lỗi này thường phát sinh khi Selenium không thể truy cập hoặc tương tác với các phần tử bên trong bóng tối DOM, một loại cấu trúc DOM được đóng gói độc đáo được nhiều trang web hiện đại sử dụng để có tính mô đun hóa tốt hơn. Trong Python, việc sử dụng Selenium để điều khiển trình duyệt có thể khó khăn với các phần tử như vậy.
Trong bối cảnh quét web từ các nền tảng như Shopee, cửa sổ bật lên hoặc biểu ngữ thường sử dụng DOM bóng, điều này có thể gây khó khăn cho việc đóng theo chương trình. Sự cố này có thể cản trở sự trôi chảy của các tác vụ tự động và làm gián đoạn việc thu thập dữ liệu.
Hướng dẫn này sẽ hướng dẫn bạn một giải pháp rõ ràng để giải quyết vấn đề 'Không thể đọc thuộc tính của Null' lỗi và cung cấp cách tiếp cận thực tế để đóng cửa sổ bật lên được nhúng trong Shadow DOM trong Shop bằng cách sử dụng Python Selenium.
Yêu cầu | Ví dụ về sử dụng |
---|---|
shadowRoot | Điều này được sử dụng để truy cập các phần tử trong Shadow DOM. Shadow DOM cô lập các thành phần nhất định khỏi cây DOM chính, yêu cầu thuộc tính ShadowRoot để truy cập chúng. Trong tập lệnh này, nó được sử dụng để xác định vị trí nút đóng bên trong cửa sổ bật lên. |
execute_script() | Phương pháp Selenium này cho phép thực thi JavaScript thô trong phiên trình duyệt. Điều này rất cần thiết khi tương tác với các phần tử DOM bóng vì các phương pháp Selenium truyền thống có thể không hoạt động. |
WebDriverWait() | Lệnh này thiết lập thời gian chờ rõ ràng trong Selenium. Nó đảm bảo rằng tập lệnh sẽ đợi cho đến khi đáp ứng một điều kiện cụ thể, chẳng hạn như một phần tử có thể nhấp vào được. Điều này rất quan trọng cho việc tải nội dung động, như đã thấy với cửa sổ bật lên của Shop. |
expected_conditions | Mô-đun này chứa các điều kiện có thể được sử dụng với WebDriverWait, chẳng hạn như khả năng hiển thị hoặc hiện diện của phần tử. Nó đảm bảo rằng các hoạt động như nhấp chuột chỉ xảy ra khi các phần tử được nhắm mục tiêu đã sẵn sàng. |
EC.presence_of_element_located() | Một điều kiện được sử dụng với WebDriverWait để đảm bảo rằng phần tử được nhắm mục tiêu có trong DOM. Điều này đặc biệt hữu ích khi chờ tải các phần tử trong Shadow DOM. |
EC.element_to_be_clickable() | Một điều kiện hữu ích khác với WebDriverWait, điều này đảm bảo phần tử được nhắm mục tiêu hiển thị và có thể nhấp vào trước khi thử bất kỳ tương tác nào, giảm lỗi trong các trang web động. |
By.CSS_SELECTOR | Phương pháp này cho phép định vị các phần tử thông qua bộ chọn CSS của chúng. Nó đặc biệt hữu ích khi nhắm mục tiêu các phần tử bên trong Shadow DOM, có thể không truy cập được bằng các phương thức XPath tiêu chuẩn. |
driver.quit() | Đảm bảo rằng phiên bản trình duyệt được đóng đúng cách sau khi tập lệnh chạy xong. Đó là cách tốt nhất quan trọng để tránh rời khỏi các phiên trình duyệt đang mở. |
Cách xử lý Shadow DOM và cửa sổ bật lên trong Selenium Web Scraping
Các tập lệnh được cung cấp ở trên nhằm giải quyết một vấn đề phổ biến gặp phải khi quét web bằng Trình điều khiển web Selenium khi tương tác với các phần tử DOM bóng. DOM bóng là một phần của trang web hoạt động tách biệt với DOM chính, thường được sử dụng trong các thành phần web phức tạp. Trong bối cảnh các trang web cóp nhặt như Shopee, cửa sổ bật lên thường xuyên xuất hiện bên trong các DOM bóng, điều này có thể dẫn đến lỗi nếu truy cập bằng các phương pháp Selenium truyền thống. Tập lệnh đầu tiên được thiết kế để đóng cửa sổ bật lên bằng cách thực thi JavaScript thông qua thực thi_script(), một công cụ mạnh mẽ cho phép Selenium chạy JavaScript thô trong ngữ cảnh trình duyệt.
Thách thức chính là các phần tử bên trong Shadow DOM không thể truy cập được bằng các lệnh Selenium phổ biến như find_element_by_xpath(). Thay vào đó, chúng tôi sử dụng JavaScript để truy cập vào Shadow DOM bằng cách sử dụng bóng gốc tài sản. Tập lệnh nhắm mục tiêu vào nút đóng của cửa sổ bật lên Shopify bằng cách trước tiên truy cập vào phần tử máy chủ bóng tối của nó, sau đó truy vấn cấu trúc bên trong của nó. Bằng cách sử dụng driver.execute_script(), tập lệnh có thể thao tác và đóng các phần tử bên trong DOM bị cô lập này. Giải pháp này hoạt động tốt khi kết hợp với tính năng chờ rõ ràng để xử lý các phần tử trang động tải không đồng bộ.
Kịch bản thứ hai giới thiệu WebDriverĐợi, một công cụ thiết yếu để quản lý thời gian của các thành phần trang động. Do cửa sổ bật lên của Shopee tải không đồng bộ nên việc tương tác trực tiếp với các thành phần này có thể gây ra lỗi. Để tránh điều này, WebDriverWait() đảm bảo rằng các phần tử mà chúng ta muốn tương tác đã được tải đầy đủ và sẵn sàng. Tập lệnh này chờ sự hiện diện của cả phần tử DOM chính và phần tử DOM bóng. phương pháp EC.presence_of_element_located() đảm bảo rằng Selenium chỉ tương tác với các phần tử sau khi chúng hiển thị và hiện diện, điều này rất quan trọng để tránh lỗi tham chiếu null.
Trong cả hai tập lệnh, chúng tôi xử lý các tình huống lỗi bằng thử ngoại trừ chặn để đảm bảo chương trình không gặp sự cố do lỗi không mong muốn, chẳng hạn như không tìm thấy phần tử. Xử lý lỗi đặc biệt quan trọng khi loại bỏ các trang web thường xuyên cập nhật cấu trúc hoặc thay đổi hành vi bật lên. Ngoài ra, các tập lệnh này tuân theo các phương pháp hay nhất bằng cách chấm dứt phiên trình duyệt bằng cách sử dụng driver.quit() sau khi thực thi để tránh rò rỉ bộ nhớ hoặc các vấn đề về hiệu suất.
Xử lý Shadow DOM và đóng cửa sổ bật lên bằng Selenium trong Python
Sử dụng Python với Selenium WebDriver để tương tác với các phần tử Shadow DOM và xử lý các cửa sổ bật lên một cách linh hoạt.
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()
Sử dụng WebDriverChờ tương tác Shadow DOM
Sử dụng tính năng chờ rõ ràng trong Selenium để đảm bảo rằng các phần tử trong Shadow DOM sẵn sàng tương tác.
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()
Xử lý nội dung động với Selenium WebDriver
Một khía cạnh quan trọng khác cần xem xét khi làm việc với Selenium WebDriver để quét web là cách xử lý nội dung động liên tục cập nhật hoặc thay đổi sau khi tải trang. Nhiều trang web hiện đại, như Shopee, sử dụng JavaScript để tải và cập nhật nội dung một cách linh hoạt. Điều này có nghĩa là các thành phần trên trang có thể không xuất hiện ngay sau khi tải trang. Trong những trường hợp như vậy, hành vi mặc định của Selenium là chờ sự kiện tải trang có thể không đủ. Sử dụng chờ đợi rõ ràng như WebDriverĐợi có thể giải quyết vấn đề này bằng cách đợi các phần tử cụ thể xuất hiện hoặc có thể nhấp vào được.
Để tìm kiếm các trang web có cửa sổ bật lên, biểu ngữ hoặc thành phần giao diện người dùng phức tạp dựa vào bóng DOM, điều cần thiết là phải biết cách tương tác với họ. Các thành phần này ẩn các thành phần trong cấu trúc DOM biệt lập mà các phương pháp truyền thống như bộ chọn XPath hoặc CSS không thể truy cập được. Sử dụng thực thi_script() lệnh giúp thu hẹp khoảng cách này bằng cách cho phép bạn chạy JavaScript trực tiếp trong trình duyệt, cấp cho bạn quyền truy cập vào Shadow DOM và cho phép tương tác với các thành phần như nút đóng hoặc trường biểu mẫu trong các phần ẩn đó của trang.
Ngoài ra, việc xử lý lỗi trở nên quan trọng trong những trường hợp như vậy. Các trang web thường có thể thay đổi cấu trúc của chúng, dẫn đến các đoạn trích bị hỏng. Sử dụng hợp lý thử ngoại trừ các khối trong Python cho phép bạn phát hiện các lỗi như JavascriptNgoại lệ và xử lý chúng một cách khéo léo, đảm bảo dụng cụ cạo không bị hỏng bất ngờ. Việc kết hợp ghi nhật ký để nắm bắt chi tiết lỗi có thể giúp xác định nguyên nhân gốc rễ và giải quyết lỗi đó trong các mẩu tin lưu niệm trong tương lai.
Câu hỏi thường gặp về cách xử lý Shadow DOM và Popup trong Selenium
- Shadow DOM là gì và tại sao nó khó truy cập?
- các shadow DOM là một cây DOM biệt lập mà các nhà phát triển web sử dụng để đóng gói các phần tử và ngăn chúng khỏi bị ảnh hưởng bởi các kiểu hoặc tập lệnh trong tài liệu chính. Rất khó truy cập vì các phương thức Selenium truyền thống không hỗ trợ tương tác trực tiếp với các phần tử DOM bóng.
- Làm thế nào execute_script() giúp tương tác với bóng DOM?
- execute_script() cho phép chạy JavaScript trực tiếp trong phiên trình duyệt, cho phép truy cập vào các phần tử DOM bóng, những phần tử này không thể truy cập được bằng các lệnh Selenium thông thường.
- Tại sao là WebDriverWait quan trọng để cạo nội dung động?
- WebDriverWait đảm bảo rằng tập lệnh chờ các điều kiện cụ thể, chẳng hạn như một phần tử có thể nhấp hoặc hiện diện, trước khi tương tác với nó. Điều này rất quan trọng để xử lý nội dung động tải không đồng bộ.
- Tôi phải làm gì khi gặp phải JavascriptException?
- JavascriptException xảy ra khi có vấn đề với việc thực thi mã JavaScript. Thực hiện xử lý lỗi bằng cách sử dụng try-except các khối có thể giúp phát hiện và quản lý các lỗi này mà không làm hỏng toàn bộ tập lệnh.
- Làm cách nào tôi có thể đóng cửa sổ bật lên động sử dụng DOM bóng?
- Để đóng các cửa sổ bật lên động được gói gọn trong Shadow DOM, trước tiên bạn cần truy cập vào Shadow Root bằng cách sử dụng execute_script() và sau đó xác định vị trí nút đóng cửa sổ bật lên bên trong DOM bóng.
Suy nghĩ cuối cùng về việc xử lý Shadow DOM trong Selenium
Việc tương tác với các phần tử DOM bóng có thể gặp khó khăn khi sử dụng Selenium để quét web. Tuy nhiên, bằng cách sử dụng việc thực thi JavaScript và chờ đợi rõ ràng, bạn có thể quản lý hiệu quả các phần tử khó truy cập bằng các phương thức tiêu chuẩn.
Bằng cách xử lý đúng cách các lỗi và kết hợp thời gian chờ, bạn có thể đảm bảo rằng các tập lệnh thu thập dữ liệu của mình mạnh mẽ và đáng tin cậy. Những kỹ thuật này sẽ giúp tránh những cạm bẫy thường gặp khi làm việc với nội dung động và cửa sổ bật lên được nhúng trong Shadow DOM, đảm bảo trải nghiệm quét mượt mà hơn.
Các nguồn và tài liệu tham khảo hữu ích để xử lý Shadow DOM trong Selenium
- Thông tin về cách tương tác với các phần tử Shadow DOM trong Selenium từ Tài liệu về Selenium WebDriver .
- Thông tin chi tiết về cách xử lý lỗi JavascriptException từ Tràn ngăn xếp .
- Hướng dẫn về các phương pháp hay nhất để thu thập nội dung động trên web bằng cách sử dụng Trăn thật .