1. Performansın analizi
Niyə optimallaşdırmaya ehtiyac var?
Təsəvvür edin ki, güclü bir avtomobiliniz var, 100 km/s sürəti üç saniyəyə çatdırır, amma yanacağı balina - plankton kimi "yeyir". Eyni səviyyədə, skriptiniz çox sürətli ola bilər, amma əgər resurs və icra müddətindən danışsaq, çox "istəkli" ola bilər. Üstəlik, resursların "sızması" onu qeyri-sabit edə bilər və bu da xətalara gətirib çıxara bilər. Optimallaşdırma bu cür problemləri aradan qaldırmağa kömək edir.
Əvvəlcə, cərrahların dediyi kimi, "kəsik" edirik. Skriptimizin performansını analiz edək ki, onun "əzab" çəkdiyi yerləri tapa bilək.
Skriptin sürəti və stabil icrasını yoxlama üsulları
Analizin sadə yollarından biri, Python-un əsas vasitələrindən biri olan time
modulundan istifadə etməkdir. Gəlin skriptimizə bir neçə sətir əlavə edək ki, hansı əməliyyatların daha çox vaxt aldığını anlayaq.
import time
start_time = time.time()
# Selenium ilə əməliyyatları yerinə yetirmək üçün kodunuzu buraya daxil edin
end_time = time.time()
print(f"İcra müddəti: {end_time - start_time} saniyə")
Bu kiçik kod fraqmenti, kodun bir hissəsinin nə qədər vaxt aldığını müəyyən etməyinizə kömək edəcək. Belə "taymerlər" köməyi ilə "dar" yerləri müəyyən etmək olar.
Zəif yerlərin identifikasiyası və onların optimallaşdırılması
Kodun "vaxt yeyən" hissəsini tapdıqdan sonra tədbirlər görmək olar. Bəlkə siz dinamik elementlərə ehtiyacdan daha çox müraciət edirsiniz, ya da kodunuz "spagettiyə" oxşayır. Birinci addım — identifikasiya, ikinci addım — tədbirlər.
Sorğuların sayının azaldılması: Çox yersiz səhifələr arası keçid və ya DOM yeniləmələri edib-edmədiyinizi yoxlayın. Məsələn, WebDriverWait
metodu istənilən elementlərin tam yüklənməsindən sonra skriptin işə düşməsinə kömək edir.
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'))
)
Verilərin cache-lənməsi: Əgər çoxsaylı hallarda eyni verilərlə işləyirsinizsə, cache barədə düşünün. Məlumatları dəyişənlərdə və ya cache-də saxlayın ki, resurs tələb edən əməliyyatları minimuma endirəsiniz.
2. Ssenarinin strukturunun yaxşılaşdırılması
Əgər kodunuzu oxumaq, stansiyaların adı və göstəricilər olmadan metro xəritəsini oxumağa bənzəyirsə, onu yaxşılaşdırmağın vaxtıdır. Optimal kod strukturu — asan anlaşılırlığın və uyğun olaraq, səhvlərə qarşı dayanıqlığın təminatıdır.
Verilənlərin pipeline-larından və optimal alqoritmik həllərdən istifadə
Kodunuzu hər bir funksiyanın və ya modulun öz məntiq hissəsinə cavab verdiyi pipeline-lar şəklində təşkil etməyi düşünün. Kodu məntiqi bloklara bölmək yalnız oxunurluğu artırmır, həm də debugging prosesini asanlaşdırır.
def load_page(url):
driver.get(url)
def extract_data():
# Məlumatların çıxarılması üçün kod
pass
def save_data():
# Məlumatların saxlanması üçün kod
pass
load_page("http://example.com")
extract_data()
save_data()
Kodun oxunurluğunu və test edilə bilənliyini artırmaq
"Bir funksiya — bir vəzifə" prinsipinə riayət edin. Bu, test etmə və refaktorinqi asanlaşdıracaq. Daha aydınlıq üçün "sehrli rəqəm" və sətirlər əvəzinə adlandırılmış konstanlardan istifadə edin.
MAX_RETRIES = 5
def fetch_data_with_retry():
for attempt in range(MAX_RETRIES):
try:
# Məlumatların alınması cəhdi
pass
except Exception as e:
print(f"Cəhd {attempt+1} uğursuz oldu: {e}")
3. Əgər kodu təkmilləşdirmək mümkündürsə - bunu edin
Gizli gözləmələr əvəzinə aşkar gözləmələrdən istifadə edin
Aşkar gözləmələr Selenium-un lazım olan elementlər göründükdə hərəkətə keçməsini dəqiq idarə etməyə imkan verir. Gizli gözləmələrə arxalanmaqdansa (məsələn, implicitly_wait
), WebDriverWait
kitabxanasından istifadə edin. Bu kitabxana xüsusi elementlər üçün müəyyən şərtlər əsasında gözləmələri tənzimləməyə imkan verir (məsələn, element görünür, klik üçün əlçatandır və s.).
Aşkar gözləmə istifadəsinə nümunə
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"))
)
Səhifənin hazır olduğuna əmin olun
Səhifə yükləndikdən sonra, xüsusən, əgər sayt asinxron metodlar (AJAX) istifadə edirsə, bütün elementlər dərhal əlçatan olmur. document.readyState
istifadə edərək sənədin tam yüklənməsini yoxlayın və sonra qarşılıqlı əlaqəyə başlayın.
Səhifənin tam yüklənməsini yoxlamağa nümunə
def wait_for_page_load(driver):
WebDriverWait(driver, 10).until(
lambda d: d.execute_script("return document.readyState") == "complete"
)
time.sleep
metodunun istifadəsini minimuma endirin
time.sleep()
metodu ssenarini sabit müddətə gözləməyə məcbur edir və xüsusilə uzun gecikmələrdə onun işləmə sürətini azaldır. Bunun yerinə daha elastik WebDriverWait
istifadə edin, hansı ki, lazım olan şərt tam həyata keçirildikdə gözləməni dayandırır.
Etibarlı element yollarından istifadə edin
HTML strukturlarına bağlı olan həssas XPath yolları sayt quruluşu dəyişdikdə tez-tez işləməz hala gələ bilər. Bunun qarşısını almaq üçün daha sabit lokatorlardan istifadə edin, məsələn, id
, name
, class
və data-*
atributları.
Etibarlı atributların istifadəsinə nümunə
# Elementi id ilə axtarırıq, əgər varsa
element = driver.find_element(By.ID, "submit_button")
# Əgər id yoxdursa, data-* atributu və ya unikal siniflərdən istifadə edə bilərsiniz
element = driver.find_element(By.CSS_SELECTOR, "[data-role='main-button']")
Pop-up pəncərələr və banerləri bağlayın
Bəzi saytlarda ssenarinin icrasına mane olan pop-up pəncərələr olur. Belə elementləri idarə etmək əsas əməliyyatların qarşısını almağa imkan verir.
Pop-up pəncərənin bağlanmasına nümunə
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 # Element tapılmadıqda və ya bağlanma mümkün olmadıqda buraxırıq
Logların idarə edilməsini konfiqurasiya edin
Loglar ssenarinin fəaliyyətini izlməyə və səhvləri aşkar etməyə kömək edir. Hər bir mühüm addım üçün daxili logging
modulundan istifadə edin ki, bu da tənzimləmə və analiz prosesini asanlaşdırır.
Logging konfiqurasiyasına nümunə
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logging.info("Ssenari başlandı")
logging.warning("Element tapılmadı, fəaliyyət davam edir")
logging.error("Xəta baş verdi")
Elementlərin görünməsini qarşılıqlı əlaqədən əvvəl yoxlayın
Bəzən elementlər səhifədə yüklənir, lakin görünmür və ya istifadə üçün əlçatan deyil. Klik etməmişdən və ya məlumat daxil etməzdən əvvəl elementin əlçatanlığına əmin olmaq üçün WebDriverWait
ilə element_to_be_clickable
şərtindən istifadə edin.
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()
Bağlantı xətalarını və vaxt bitmələrini idarə edin
Veb saytlardan məlumat çıxararkən bəzən əlaqə xətaları və ya vaxt limiti xətaları baş verir, server sorğulara cavab göndərmir. Bu cür səhvlərin qarşısını almaq üçün ssenari müvəqqəti əlçatmazlıq zamanı hərəkətləri keçib və ya təkrarlamağı bacarmalıdır.
Bağlantı xətalarının idarə olunmasına nümunə
from selenium.common.exceptions import TimeoutException
try:
driver.get("https://example.com")
except TimeoutException:
logging.error("Səhifəyə qoşulmaq mümkün olmadı. Növbəti vəzifəyə keçirik.")
Brauzeri bağlayın
Resurs yığılmasının qarşısını almaq və səhvlər zamanı brauzeri bağlamaq üçün həmişə try-finally
və ya alternativ üsullardan istifadə edin ki, fəaliyyət düzgün şəkildə yekunlaşsın.
try:
# Selenium ilə fəaliyyətləriniz
pass
finally:
driver.quit() # Brauzerin bağlanması
4. Yeni başlayanların tipik səhvləri
Web-draiverləri və kitabxanaları yeniləməyi unutmayın. Bu, brauzerin yenilənmələri və Selenium API-dəki dəyişikliklərlə bağlı uyğunsuzluqların və səhvlərin qarşısını almağa kömək edəcək.
Sonda isə, əgər ssenariniz tez-tez "çökürsə" və aydın səbəbi yoxdursa, ola bilsin ki, test serveriniz tez-tez sorğulara blok qoyur. Yoxlayın, giriş qaydalarını pozmursunuzmu, və proxy-serverlərdən istifadə etməyi və ya sorğuların tezliyini tənzimləməyi düşünün.
Ssenarilərin optimallaşdırılması sadəcə texniki bir iş deyil, təcrübə ilə gələn bir sənətdir. Ümid edirəm ki, bugünkü tövsiyələr sizə hər hansı bir yükə dözə bilən etibarlı və sabit ssenarilər yaratmaqda kömək edəcək.
GO TO FULL VERSION