Как сохранить элементы оригинальной страницы с селеном после открытия ссылки, созданной javascript, и возврата на исходную страницу - PullRequest
0 голосов
/ 03 января 2019

Кажется невозможным или очень сложным сохранить оригинальные элементы в веб-драйвере селена после перемещения другой страницы по ссылке, сгенерированной javascript. Как я могу это сделать?

Я пытаюсь выполнить очистку веб-страницы для определенной веб-страницы, используя следующие компоненты:

  • Ubuntu 18.04.1 LTS
  • Python 3.6.1
  • Селен (пакет Python) 3.141.0
  • Google Chrome 71.0.3578.98
  • ChromeDriver 2.45.615279

Веб-страница содержит ссылки, которые "href" - это функция javascript, например:

<a href="javascript:funcName(10, 24, 100)"></a>

Определение функции примерно такое:

var funcName = function(arg1, arg2, arg3) {
    var url = 'XXXXXXXX' // dynamically generated using arguments
    var form = $('<form>', {
        name: 'formName',
        action: url,
        method: 'post'
    });
    // Some procedure to enhance the form element with input arguments.
    form.submit()
}

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

Дело в том, что оригинальная веб-страница содержит много ссылок, и я бы хотел поочередно просматривать перенаправленные страницы. Однако, кажется невозможным получить URL перенаправленной страницы без фактического нажатия на ссылку (), так как она перенаправляется динамически генерируемым почтовым запросом. С другой стороны, если я щелкну по нему и перейду на перенаправленную страницу, элементы, которые я использовал для исходной веб-страницы, больше не могут быть использованы, поэтому после возвращения на исходную страницу мне нужно получить следующую ссылку с самого начала , Это кажется очень излишним.

Пример кода Python

for a in driver.find_elements_by_css_selector(.some-class-name):
    a.click()  # this redirects me to another page
    print(driver.current_url)  # this shows the redirected page
    driver.back()
    print(driver.current_url). # this shows the original page
    # After coming back to the original page and when doing looping process, Python returns StaleElementReferenceException
    # because a is attached to the original page before redirected.

Что я сделал, чтобы сохранить элементы оригинальной страницы, но не сработало:

1. Скопировать элемент (или драйвер) объекта

from copy import deepcopy
for a in driver.find_elements_by_css_selector(.some-class-name):
    a2 = deepcopy(a)
    a2.click()  # this redirects me to another page
    print(driver.current_url)  # Expected result is that this remains the original web page, but didn't

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

TypeError: can't pickle _thread.lock objects

2.Открыть перенаправленную страницу в новой вкладке

from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys

for a in driver.find_elements_by_css_selector(.some-class-name):

    action = ActionChains(driver)

    # Expected result is the following open the redirected page in a new tab, and CONTROL + TAB changes between tabs
    action.key_down(Keys.CONTROL).click(a).key_down(Keys.CONTROL).perform()  
    driver.send_keys(Keys.CONTROL + Keys.TAB)

Однако это не открыло новую вкладку, просто перейдите на перенаправленную страницу в той же вкладке.

Если не существует простого способа, я сделаю это, создав объект списка или словаря для хранения ссылок, которые я уже удалил, и каждый раз после очистки перенаправленной страницы я снова анализирую исходную страницу и пропускаю ссылка, которая уже была проверена. Но я не хочу этого делать, потому что это очень избыточно.

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Даже если вы вернете ту же страницу, но селен не знает, что это та же страница, селен будет воспринимать ее как новую страницу.links, найденный перед циклом for, не принадлежит новой странице.Вам нужно снова найти ссылки на новой странице и назначить их той же переменной links внутри цикла for.Использование индекса для перехода к следующей ссылке.

links = driver.find_elements_by_css_selector(.some-class-name)

for i in range(0, len(links)):
    links[i].click()  # this redirects me to another page
    print(driver.current_url)  # this shows the redirected page
    driver.back()
    print(driver.current_url). 

    # Important: find the links again on the page back from redirected page
    # to resolve the StaleElementReferenceException.
    links = driver.find_elements_by_css_selector(.some-class-name)
0 голосов
/ 03 января 2019

Я выбрал способ создания другого экземпляра веб-драйвера.

driver = webdriver.Chrome()
driver_sub = webdriver.Chrome()

driver.get(url)
driver_sub.get(url)  # access the same page with different instance

for a in driver.find_elements_by_css_selector('.some-class-name'):
    script = a.get_attribute('href')
    driver_sub.execute_script(script)
    # do some work on the redirected page with driver_sub
    driver_sub.execute_script('window.history.go(-1)')  # this is almost same as driver_sub.back()
...