Перейти к содержимому

Школа тест-менеджеров v. 2.0
онлайн, начало 16 октября
Школа для начинающих тестировщиков
онлайн, начало 17 октября
Python для начинающих
онлайн, начало 16 октября
Организация автоматизированного тестирования
онлайн, начало 18 октября
Фотография

selenium.common.exceptions.StaleElementReferenceException:

selenium python parsing

  • Авторизуйтесь для ответа в теме
Сообщений в теме: 3

#1 dima96

dima96

    Новый участник

  • Members
  • Pip
  • 2 сообщений
  • ФИО:Дмитрий Иванов

Отправлено 20 Февраль 2019 - 18:15

Пытаюсь  написать парсер на питоне, используя селениум. Суть парсера в том, что нужно сначал повытаскивать url-адреса (их около 50 000). А потом уже парсить данные из каждой страницы.

Столкнулся с проблемой. Пытался выставлять тайминги до 10 секунд - не помогло. Самое интересное, что эта ошибка появляется постоянно в разных местах. По-моему, во всех случаях она была связана с выпадающим списком. Тут список довольно непростой. Вот его особенности.

1. Список открывается при наведении на него мышью.

2. Для того, чтобы получить url каждого пункта я навожу на него, кликаю на пункт меню, вытаскиваю url.

2.1. Каждый пункт списка состоит из подпунктов. Они видны (просто в зависимости от выбранного меню у них меняется id). Я  кликаю по ним, вытаскиваю url (без наведения), после чего навожу на список и перехожу к следующему пункту. И так цикл повторяется.

3. Изначльно список состоит из 6 пунктов (по дефолту в списке стоит значение Default). Но при клике на пункт меню он исчезает из списка и соответственно их там становится 5.

 

Вот мой код

    #Пункты из выпадающего меню
    a_list_text = []
    li_more = ul_nav.find_element_by_css_selector('li.r.more')
    ActionChains(driver).move_to_element(li_more).perform()
    a_more_list = li_more.find_elements_by_css_selector('div > div > p > a')
    
    #Добавляем пункты в список
    for a_more in a_more_list:
        a_list_text.append(a_more.text)

    #Проходим по пунктам
    for a in a_list_text:
        li_more = ul_nav.find_element_by_css_selector('li.r.more')
        ActionChains(driver).move_to_element(li_more).perform()
        #Создаём ещё один список с пунктами из меню
        a_more_list = li_more.find_elements_by_css_selector('div > div > p > a')

        for a_more_ in a_more_list:
            #Так как пункты в списке меняются местами, сверяем равен ли текущий пункт выбранному. Если да, запускаем цикл, если нет - переходим к следкющему
            if a == a_more_.text:
                a_more_.click()
                # time.sleep(2)
                print(driver.current_url)

                #Вытаскиваем подпункты
                more_sub_ul_nav = driver.find_element_by_css_selector("ul.sub-menu.subactive[style = 'display: block;']")
                more_sub_a_more_list = more_sub_ul_nav.find_elements_by_css_selector('li > a')
                
                #Проходим по подпунктам (они видны, без наведения)
                for more_sub_a_more in more_sub_a_more_list:
                    more_sub_a_more.click()
                    # time.sleep(2)
                    print(driver.current_url)

                #Когда прошли по все подпунктам - обрываем цикл и переходим к следующему пункту
                break
Traceback (most recent call last):
  File "all_links.py", line 90, in <module>
    count += parse(driver, 'https://****' + link_match.get("href"), count)
  File "all_links.py", line 48, in parse
    a_list_text.append(a_more.text)
  File "/home/m0nte-cr1st0/.local/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 76, in text
    return self._execute(Command.GET_ELEMENT_TEXT)['value']
  File "/home/m0nte-cr1st0/.local/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "/home/m0nte-cr1st0/.local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/home/m0nte-cr1st0/.local/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: The element reference of <a href=""> 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

В принципе, можно как-то try/except прикрутить, наверное. Я пробовал, но было 2 проблемы:

1. "Съедались" некоторые ссылки (видимо, неверно except настроил)

2. Всё-равно вылетала ошибка спустя какое-то время (видимо, неверно try вставил)

 

Уже который день пытаюсь побороть проблему - не получается. Может, кто-то что-то подскажет?.. Не знаю, куда ещё обратиться(

https://imgur.com/SUiVgiS

https://imgur.com/99Wqghy


  • 0

#2 checo

checo

    Опытный участник

  • Members
  • PipPipPipPip
  • 374 сообщений
  • Город:Н.Новгород

Отправлено 22 Февраль 2019 - 13:14

Уверены, что Selenuim тут вообще нужен? Проще просто из исходника страницы всё получить. Или, если каждый раз список или адрес запрашивается, то отправлять такие же запросы и парсить. Модуль requests в помощь.


  • 0

#3 dima96

dima96

    Новый участник

  • Members
  • Pip
  • 2 сообщений
  • ФИО:Дмитрий Иванов

Отправлено 22 Февраль 2019 - 18:17

Уверены, что Selenuim тут вообще нужен? Проще просто из исходника страницы всё получить. Или, если каждый раз список или адрес запрашивается, то отправлять такие же запросы и парсить. Модуль requests в помощь.

Уверен, можно было бы lxml или bs распарсить - распарсил бы. тут данные с js передаются, увы(


  • 0

#4 Likin

Likin

    Новый участник

  • Members
  • Pip
  • 1 сообщений
  • ФИО:Ликин Александр

Отправлено 07 Май 2019 - 18:39

Пытаюсь  написать парсер на питоне, используя селениум. Суть парсера в том, что нужно сначал повытаскивать url-адреса (их около 50 000). А потом уже парсить данные из каждой страницы.

Столкнулся с проблемой. Пытался выставлять тайминги до 10 секунд - не помогло. Самое интересное, что эта ошибка появляется постоянно в разных местах. По-моему, во всех случаях она была связана с выпадающим списком. Тут список довольно непростой. Вот его особенности.

1. Список открывается при наведении на него мышью.

2. Для того, чтобы получить url каждого пункта я навожу на него, кликаю на пункт меню, вытаскиваю url.

2.1. Каждый пункт списка состоит из подпунктов. Они видны (просто в зависимости от выбранного меню у них меняется id). Я  кликаю по ним, вытаскиваю url (без наведения), после чего навожу на список и перехожу к следующему пункту. И так цикл повторяется.

3. Изначльно список состоит из 6 пунктов (по дефолту в списке стоит значение Default). Но при клике на пункт меню он исчезает из списка и соответственно их там становится 5.

 

Вот мой код

    #Пункты из выпадающего меню
    a_list_text = []
    li_more = ul_nav.find_element_by_css_selector('li.r.more')
    ActionChains(driver).move_to_element(li_more).perform()
    a_more_list = li_more.find_elements_by_css_selector('div > div > p > a')
    
    #Добавляем пункты в список
    for a_more in a_more_list:
        a_list_text.append(a_more.text)

    #Проходим по пунктам
    for a in a_list_text:
        li_more = ul_nav.find_element_by_css_selector('li.r.more')
        ActionChains(driver).move_to_element(li_more).perform()
        #Создаём ещё один список с пунктами из меню
        a_more_list = li_more.find_elements_by_css_selector('div > div > p > a')

        for a_more_ in a_more_list:
            #Так как пункты в списке меняются местами, сверяем равен ли текущий пункт выбранному. Если да, запускаем цикл, если нет - переходим к следкющему
            if a == a_more_.text:
                a_more_.click()
                # time.sleep(2)
                print(driver.current_url)

                #Вытаскиваем подпункты
                more_sub_ul_nav = driver.find_element_by_css_selector("ul.sub-menu.subactive[style = 'display: block;']")
                more_sub_a_more_list = more_sub_ul_nav.find_elements_by_css_selector('li > a')
                
                #Проходим по подпунктам (они видны, без наведения)
                for more_sub_a_more in more_sub_a_more_list:
                    more_sub_a_more.click()
                    # time.sleep(2)
                    print(driver.current_url)

                #Когда прошли по все подпунктам - обрываем цикл и переходим к следующему пункту
                break
Traceback (most recent call last):
  File "all_links.py", line 90, in <module>
    count += parse(driver, 'https://****' + link_match.get("href"), count)
  File "all_links.py", line 48, in parse
    a_list_text.append(a_more.text)
  File "/home/m0nte-cr1st0/.local/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 76, in text
    return self._execute(Command.GET_ELEMENT_TEXT)['value']
  File "/home/m0nte-cr1st0/.local/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "/home/m0nte-cr1st0/.local/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/home/m0nte-cr1st0/.local/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: The element reference of <a href=""> 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

В принципе, можно как-то try/except прикрутить, наверное. Я пробовал, но было 2 проблемы:

1. "Съедались" некоторые ссылки (видимо, неверно except настроил)

2. Всё-равно вылетала ошибка спустя какое-то время (видимо, неверно try вставил)

 

Уже который день пытаюсь побороть проблему - не получается. Может, кто-то что-то подскажет?.. Не знаю, куда ещё обратиться(

https://imgur.com/SUiVgiS

https://imgur.com/99Wqghy

 Ошибка связана с тем что страница обновилась, а у найденного элемента айдишник старый.
Решение перед использованием элемента искать его по новой.


  • 0


Selenium 2.0: стартовый уровень
онлайн
Программирование на Java для тестировщиков
онлайн
Автоматизация функционального тестирования
онлайн
Selenium WebDriver: полное руководство
онлайн




Темы с аналогичным тегами selenium, python, parsing

Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных

Яндекс.Метрика
Реклама на портале