Обход исключений устаревших элементов в Selenium - PullRequest
0 голосов
/ 16 июня 2020

Я прочитал несколько статей на этом сайте, касающихся исключения StaleElementReferenceException, и мне известно, что эта ошибка вызвана тем, что элемент больше не находится в DOM сайта. Что я пытаюсь сделать, так это щелкнуть нижние ссылки на этой веб-странице, чтобы перейти на go и увидеть списки на следующей странице. Я попробовал несколько способов обойти это исключение, предоставленное мне, и не нашел ни одного из них. Вот пример кода, который я пробовал, и то, что, как я думал, может выполнить sh.

driver = webdriver.Chrome(r'C:\Users\Hank\Desktop\chromedriver_win32\chromedriver.exe')
driver.get('https://steamcommunity.com/market/listings/440/Unusual%20Old%20Guadalajara')
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait as wait
from selenium.webdriver.support.expected_conditions import presence_of_element_located
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import StaleElementReferenceException
action = ActionChains(driver)
page_links = wait(driver, 10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '[class^=market_paging_pagelink]')))
try:
    action.move_to_element(page_links[1]).click().perform()
except StaleElementReferenceException as Exception:
    print("Exception received, trying again")
    time.sleep(5)
    page_links = wait(driver, 10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '[class^=market_paging_pagelink]')))
    action.move_to_element(page_links[1]).click().perform()

Я надеялся, что этот сегмент кода попытается перейти к элементу внизу, щелкните или верните сообщение об ошибке и попробуйте еще раз, удачно во второй раз. Вместо этого код просто снова выдает ошибку. Если на мой вопрос уже был дан ответ, направьте меня по соответствующей ссылке. Спасибо!

1 Ответ

1 голос
/ 16 июня 2020

Подход, который я обычно использую go, заключается в том, чтобы нажимать «Следующая страница», пока кнопка не станет отключенной / невидимой.

Вот рабочий пример, основанный на вашей странице. Очевидно, вы должны делать все, что уместно в цикле while; Для примера я выбрал захват цен.

url="https://steamcommunity.com/market/listings/440/Unusual%20Old%20Guadalajara"
driver.get(url)

next_button=wait(driver, 10).until(EC.presence_of_element_located((By.ID,'searchResults_btn_next')))

# capture the start value from "Showing x-xx of 22 results"
#need this to check against later
ref_val=wait(driver, 10).until(EC.presence_of_element_located((By.ID,'searchResults_start'))).text

while next_button.get_attribute('class') == 'pagebtn':
    next_button.click()
    #wait until ref_val has changed
    wait(driver, 10).until(lambda driver: wait(driver, 10).until(EC.presence_of_element_located((By.ID,'searchResults_start'))).text != ref_val)

    # ====== Do whatever relevant here =============================
    page_num=wait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR,'.market_paging_pagelink.active'))).text
    print(f"Prices from page {page_num}")
    prices = wait(driver, 10).until(EC.presence_of_all_elements_located(
        (By.XPATH, ".//span[@class='market_listing_price market_listing_price_with_fee']")))
    for price in prices:
        print(price.text)
    #================================================================

    #get the new reference value
    ref_val = wait(driver, 10).until(EC.presence_of_element_located((By.ID, 'searchResults_start'))).text
...