StaleElementException при итерации с Python - PullRequest
0 голосов
/ 06 декабря 2018

Я пытаюсь создать простой веб-скребок для результатов Amazon.Когда я перебираю результаты, я иногда попадаю на страницу 5 (иногда только на страницу 2) результатов, а затем выбрасывается StaleElementException.Когда я смотрю в браузере после того, как сгенерировано исключение, я вижу, что драйвер / страница не прокручивались вниз до номера страницы (нижняя строка).

Мой код:

driver.get('https://www.amazon.com/s/ref=nb_sb_noss_1?url=search-alias%3Daps&field-keywords=sonicare+toothbrush')

for page in range(1,last_page_number +1):

    driver.implicitly_wait(10)

    bottom_bar = driver.find_element_by_class_name('pagnCur')
    driver.execute_script("arguments[0].scrollIntoView(true);", bottom_bar)

    current_page_number = int(driver.find_element_by_class_name('pagnCur').text)

    if page == current_page_number:
        next_page = driver.find_element_by_xpath('//div[@id="pagn"]/span[@class="pagnLink"]/a[text()="{0}"]'.format(current_page_number+1))
        next_page.click()
        print('page #',page,': going to next page')
    else:
        print('page #: ', page,'error')

Я смотрел на этот вопрос , и я предполагаю, что подобное исправление может быть применено, но я не уверен, как найти что-то на исчезающей странице.Кроме того, исходя из того, насколько быстро выполняются операторы печати, я вижу, что implicitly_wait(10) фактически не ждет полных 10 секунд.

Исключение указывает на строку, начинающуюся с "driver.execute_script».Это исключение:

StaleElementReferenceException: Message: The element reference of <span class="pagnCur"> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed

Иногда я получаю ValueError:

ValueError: invalid literal for int() with base 10: ''

Так что эти ошибки / исключения заставляют меня поверить, что что-то происходит с ожиданиемстраница полностью обновляется.

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Кажется, ты почти был там.

Сохраняя вашу концепцию прокрутки до scrollIntoView() и печати парой полезных отладочных сообщений, я внес некоторые незначительные корректировки, вызывая WebDriverWait и вы можете использовать следующее решение:

  • Кодовый блок:

    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    options = Options()
    options.add_argument("start-maximized")
    options.add_argument('disable-infobars')
    options.add_argument("--disable-extensions")
    driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
    driver.get("https://www.amazon.com/s/ref=nb_sb_noss_1?url=search-alias%3Daps&field-keywords=sonicare+toothbrush")
    while True:
        try:
            current_page_number_element = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "span.pagnCur")))
            driver.execute_script("arguments[0].scrollIntoView(true);", current_page_number_element)
            current_page_number = current_page_number_element.get_attribute("innerHTML")
            WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "span.pagnNextArrow"))).click()
            print("page # {} : going to next page".format(current_page_number))
        except:
            print("page # {} : error, no more pages".format(current_page_number))
            break
    driver.quit()
    
  • Консольный вывод:

    page # 1 : going to next page
    page # 2 : going to next page
    page # 3 : going to next page
    page # 4 : going to next page
    page # 5 : going to next page
    page # 6 : going to next page
    page # 7 : going to next page
    page # 8 : going to next page
    page # 9 : going to next page
    page # 10 : going to next page
    page # 11 : going to next page
    page # 12 : going to next page
    page # 13 : going to next page
    page # 14 : going to next page
    page # 15 : going to next page
    page # 16 : going to next page
    page # 17 : going to next page
    page # 18 : going to next page
    page # 19 : going to next page
    page # 20 : error, no more pages
    
0 голосов
/ 06 декабря 2018

Если вы просто хотите, чтобы ваш скрипт перебирал все страницы результатов, вам не нужна сложная логика - просто нажмите кнопку «Далее», пока это возможно:

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

driver = webdriver.Chrome()

driver.get('https://www.amazon.com/s/ref=nb_sb_noss_1?url=search-alias%3Daps&field-keywords=sonicare+toothbrush')

while True:
    try:
        wait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a > span#pagnNextString'))).click()
    except TimeoutException:
        break

PS Также обратите внимание, чтоimplicitly_wait(10) не должно ждать полных 10 секунд , но ожидает до 10 секунд, пока элемент не появится в HTML DOM .Поэтому, если элемент найден в течение 1 или 2 секунд, ожидание завершено, и вы не будете ждать оставшиеся 8-9 секунд ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...