Получение «StaleElementReferenceException» при доступе к опциям в выпадающем меню - PullRequest
0 голосов
/ 05 февраля 2020

В Python и Selenium я заполняю форму, отправляю ее, а затем очищаю полученную многостраничную таблицу, которая появляется на странице под формой. После очистки каждой страницы этой таблицы я сбрасываю форму и пытаюсь снова заполнить форму. Однако выпадающее меню вызывает код.

Я пытался заставить драйвер дождаться появления выпадающего меню после сброса формы, но это не помогает. Я все еще получаю сообщение об ошибке StaleReferenceElementException в строке if option.text == state:

 StaleElementReferenceException: Message: The element reference of <option> 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

Как многократно отправлять форму для различных параметров в раскрывающемся меню?

states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 
          'Colorado', 'Connecticut', 'Delaware', 'District of Columbia', 
          'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana',
          'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland',
          'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri',
          'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 
          'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio',
          'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina',
          'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia',
          'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']

# Construct browser and link
browser = webdriver.Firefox(executable_path='/usr/local/bin/geckodriver')
url = 'https://myaccount.rid.org/Public/Search/Member.aspx'
ignored_exceptions = (StaleElementReferenceException,)

# Navigate to link
browser.get(url) 

try:
    # For each state
    for state in states:
        print('Searching ' + state)
        # Set category and select state menu
        category = Select(browser.find_element_by_name('ctl00$FormContentPlaceHolder$Panel$categoryDropDownList'))
        category.select_by_value('a027b6c0-07bb-4301-b9b5-1b38dcdc59b6')
        state_menu = Select(WebDriverWait(browser, 10, ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located((By.ID, 'FormContentPlaceHolder_Panel_stateDropDownList'))))
        options = state_menu.options

        for option in options:
            if option.text == state:
                state_menu.select_by_value(option.get_attribute('value'))
                browser.find_element_by_name('ctl00$FormContentPlaceHolder$Panel$searchButtonStrip$searchButton').click()

                # Scrape the first page of results
                results = []
                curr_page = 1
                onFirstPage = True
                scrape_page(curr_page)

                # Reset form
                browser.find_element_by_name('ctl00$FormContentPlaceHolder$Panel$searchButtonStrip$resetButton').click()
                break
finally:
    pass

1 Ответ

0 голосов
/ 05 февраля 2020

В момент выбора опции ссылки на элементы будут обновлены, и вы не сможете использовать более старые ссылки. Причина, по которой вы получаете исключение, заключается в том, что вы пытаетесь получить атрибут из option, который больше не действителен.

Вместо использования итерации я бы использовал xpath, чтобы выбрать параметр, как показано ниже

        state_menu = WebDriverWait(browser, 10, ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located((By.ID, 'FormContentPlaceHolder_Panel_stateDropDownList')))
        #options = state_menu.options <== replace this line with below line
        option = state_menu.find_element_by_xpath("//option[.='" + state + "']")

        #for option in options: <== remove this line
            # if option.text == state: <== remove this
        option.click()
        browser.find_element_by_name('ctl00$FormContentPlaceHolder$Panel$searchButtonStrip$searchButton').click()

        # Scrape the first page of results
        results = []
        curr_page = 1
        onFirstPage = True
        scrape_page(curr_page)
        # Reset form
        browser.find_element_by_name('ctl00$FormContentPlaceHolder$Panel$searchButtonStrip$resetButton').click()
...