CodeGym /Các khóa học /Python SELF VI /Tối ưu hóa script để chạy ổn định và giảm thiểu lỗi

Tối ưu hóa script để chạy ổn định và giảm thiểu lỗi

Python SELF VI
Mức độ , Bài học
Có sẵn

1. Phân tích hiệu suất

Tại sao phải tối ưu hóa?

Hãy tưởng tượng một chiếc xe hơi mạnh mẽ có thể tăng tốc lên 100 km/h trong 3 giây, nhưng lại tiêu thụ xăng như cá voi tiêu thụ phù du. Script của bạn cũng có thể rất nhanh, nhưng sẽ rất "hao tài nguyên" khi nói đến tài nguyên và thời gian thực thi. Hơn nữa, "rò rỉ" tài nguyên có thể làm script mất ổn định, dẫn đến lỗi. Tối ưu hóa giúp tránh những vấn đề đó.

Đầu tiên, như các bác sĩ phẫu thuật nói, "mổ xẻ" trước đã. Hãy thực hiện phân tích hiệu suất script của chúng ta để hiểu nó đang "khổ sở" ở đâu.

Các phương pháp kiểm tra tốc độ và độ ổn định của script

Một trong những cách đơn giản để phân tích là sử dụng các công cụ cơ bản của Python như module time. Hãy thêm vài dòng code vào script để xem thao tác nào tốn thời gian nhất.

Python

import time

start_time = time.time()
# Đây là code của bạn để thực hiện các thao tác với Selenium
end_time = time.time()

print(f"Thời gian thực thi: {end_time - start_time} giây")
  

Đoạn code nhỏ này sẽ giúp bạn xác định thời gian thực hiện một phần code. Với những "đồng hồ bấm giờ" này, bạn có thể xác định các "điểm tắc nghẽn".

Xác định điểm yếu và tối ưu chúng

Ngay khi bạn tìm thấy phần code chiếm nhiều thời gian, hãy thực hiện các biện pháp. Có thể bạn đang truy cập vào các thành phần động nhiều hơn mức cần thiết, hoặc code của bạn trở nên giống như "mỳ spaghetti". Bước đầu tiên là xác định, bước thứ hai là hành động.

Giảm số lượng yêu cầu: Kiểm tra xem bạn có thực hiện quá nhiều chuyển đổi giữa các trang hoặc cập nhật DOM không cần thiết không. Ví dụ, sử dụng phương pháp WebDriverWait giúp script chỉ chạy sau khi tất cả các thành phần mong muốn đã được tải hoàn toàn.

Python

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, 'myDynamicElement'))
)
  

Cache dữ liệu: Nếu bạn làm việc với cùng một dữ liệu nhiều lần, hãy nghĩ đến việc sử dụng cache. Lưu trữ dữ liệu trong biến hoặc cache để giảm thiểu các thao tác tốn tài nguyên.

2. Cải thiện cấu trúc script

Nếu code của bạn khó đọc như bản đồ tàu điện ngầm không có chỉ dẫn hoặc tên ga, thì đã đến lúc cải thiện nó. Một cấu trúc code tối ưu đảm bảo dễ hiểu và do đó ít gặp lỗi hơn.

Sử dụng pipeline dữ liệu và các giải pháp thuật toán tối ưu

Hãy nghĩ đến việc cấu trúc code của bạn dưới dạng pipeline, nơi mỗi hàm hoặc module chịu trách nhiệm cho một phần logic của nó. Việc chia code thành các khối logic không chỉ cải thiện khả năng đọc mà còn giúp dễ dàng gỡ lỗi.

Python

def load_page(url):
    driver.get(url)

def extract_data():
    # Code để lấy dữ liệu
    pass

def save_data():
    # Code để lưu dữ liệu
    pass

load_page("http://example.com")
extract_data()
save_data()
  

Cải thiện khả năng đọc và kiểm tra code

Tuân theo nguyên tắc "một hàm — một nhiệm vụ". Điều này sẽ làm cho việc kiểm tra và refactor trở nên dễ dàng hơn. Sử dụng các hằng số có tên thay vì "con số ma thuật" và chuỗi để làm rõ hơn.

Python

MAX_RETRIES = 5

def fetch_data_with_retry():
    for attempt in range(MAX_RETRIES):
        try:
            # Thử yêu cầu dữ liệu
            pass
        except Exception as e:
            print(f"Thử lần {attempt+1} thất bại: {e}")
  

3. Nếu code có thể cải thiện - phải cải thiện

Sử dụng explicit waits thay vì implicit

Explicit waits cho phép bạn kiểm soát chính xác khi nào Selenium bắt đầu thực hiện hành động, đợi đến khi phần tử cần thiết xuất hiện. Thay vì dựa vào implicit waits (vd. implicitly_wait), hãy sử dụng thư viện WebDriverWait, cho phép bạn thiết lập các điều kiện chờ cụ thể (vd. phần tử hiển thị, có thể nhấp chuột, v.v.).

Ví dụ sử dụng explicit wait

Python

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.ID, "target_element"))
)
  

Đảm bảo trang đã sẵn sàng

Sau khi tải trang, không phải tất cả các thành phần đều sẵn sàng ngay lập tức, đặc biệt nếu trang web sử dụng các phương pháp tải không đồng bộ (AJAX). Sử dụng document.readyState để kiểm tra xem tài liệu đã tải xong trước khi bắt đầu tương tác.

Ví dụ kiểm tra xem trang đã tải xong

Python

def wait_for_page_load(driver):
    WebDriverWait(driver, 10).until(
        lambda d: d.execute_script("return document.readyState") == "complete"
    )
  

Giảm thiểu sử dụng time.sleep

Phương pháp time.sleep() buộc script phải chờ một khoảng thời gian cố định và làm chậm quá trình chạy, đặc biệt nếu có độ trễ dài. Thay vào đó, sử dụng WebDriverWait, linh hoạt hơn và kết thúc quá trình chờ ngay khi điều kiện được đáp ứng.

Sử dụng đường dẫn ổn định để xác định phần tử

Các định vị mong manh, chẳng hạn như đường dẫn XPath phụ thuộc vào cấu trúc HTML cụ thể, có thể nhanh chóng mất hiệu lực nếu cấu trúc trang thay đổi. Để tránh điều này, hãy sử dụng các định vị ổn định hơn, ví dụ như các thuộc tính id, name, classdata-*.

Ví dụ sử dụng thuộc tính ổn định

Python

# Dùng id nếu có sẵn
element = driver.find_element(By.ID, "submit_button")

# Nếu không có id, có thể dùng thuộc tính data-* hoặc class duy nhất
element = driver.find_element(By.CSS_SELECTOR, "[data-role='main-button']")
  

Đóng các popup và banner

Một số trang web chứa popup gây cản trở việc chạy script. Xử lý các thành phần này sẽ giúp tránh sự cố trong quá trình thực hiện.

Ví dụ đóng popup

Python

from selenium.common.exceptions import ElementClickInterceptedException

try:
    close_popup = driver.find_element(By.CLASS_NAME, "popup-close-button")
    close_popup.click()
except (NoSuchElementException, ElementClickInterceptedException):
    pass  # Bỏ qua nếu không tìm thấy phần tử hoặc không thể đóng
  

Cấu hình logging

Logging giúp theo dõi các hành động của script và phát hiện lỗi trong quá trình chạy. Sử dụng module logging tích hợp sẵn để log từng bước quan trọng trong script, giúp bạn dễ dàng debug và phân tích.

Ví dụ cấu hình logging

Python

import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

logging.info("Script đã khởi chạy")
logging.warning("Không tìm thấy phần tử, tiếp tục thực hiện")
logging.error("Xuất hiện lỗi")
  

Kiểm tra khả năng hiển thị của phần tử trước khi tương tác

Đôi khi các phần tử đã tải trên trang nhưng không hiển thị hoặc không thể tương tác. Sử dụng WebDriverWait với điều kiện element_to_be_clickable để đảm bảo phần tử sẵn sàng trước khi nhấp chuột hoặc nhập dữ liệu.

Python

from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.ID, "button_id"))
)
element.click()
  

Xử lý các lỗi kết nối và timeout

Khi scrape dữ liệu từ các trang web, đôi khi xảy ra lỗi kết nối hoặc timeout khi server không phản hồi các yêu cầu. Thiết lập xử lý các lỗi như vậy để script có thể bỏ qua hoặc thực hiện lại hành động trong trường hợp trang web tạm thời không khả dụng.

Ví dụ xử lý lỗi kết nối

Python

from selenium.common.exceptions import TimeoutException

try:
    driver.get("https://example.com")
except TimeoutException:
    logging.error("Không thể kết nối đến trang. Chuyển sang tác vụ tiếp theo.")
  

Đóng trình duyệt

Để tránh tích lũy tài nguyên và đảm bảo trình duyệt đóng đúng cách trong trường hợp xảy ra lỗi, luôn sử dụng try-finally hoặc cấu trúc phù hợp để hoàn tất script một cách chính xác.

Python

try:
    # Các thao tác với Selenium
    pass
finally:
    driver.quit()  # Đóng trình duyệt
  

4. Lỗi phổ biến của người mới

Đừng quên cập nhật các driver và thư viện. Điều này sẽ giúp tránh các lỗi không tương thích và các vấn đề liên quan đến cập nhật trình duyệt hoặc thay đổi API của Selenium.

Và cuối cùng, nếu script của bạn thường xuyên "sập" mà không có lý do rõ ràng, có thể server thử nghiệm của bạn đang chặn các yêu cầu quá thường xuyên. Hãy kiểm tra xem bạn có vi phạm quy tắc truy cập hay không và cân nhắc sử dụng proxy server hoặc điều chỉnh tần suất yêu cầu.

Tối ưu hóa script không chỉ là một nhiệm vụ kỹ thuật mà còn là một nghệ thuật, cần thời gian để thành thạo. Hy vọng các mẹo hôm nay sẽ giúp bạn tạo ra các script đáng tin cậy và ổn định, chịu được bất kỳ tải nào.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION