当前位置: 首页 > 知识库问答 >
问题:

如何在打开由javascript生成的链接后保留原始页面的元素并返回到原始页面

钱展
2023-03-14

通过javascript生成的链接移动另一个页面后,要在selenium的网络驱动程序中保留原始元素似乎是不可能或非常复杂的。我该怎么做呢?

我试图使用以下组件为特定的网页做网页抓取:

  • Ubuntu 18.04。1 LTS
  • Python 3.6。1
  • Selenium(Python包)3.141。0
  • 谷歌浏览器71.0。3578.98
  • 铬驱动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()
}

上面的post请求将我重定向到另一个我想抓取的页面。

问题是原始网页包括许多链接,我想一个接一个地刮重定向页面。然而,如果不实际单击链接(

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

我尝试了驱动程序本身的deepcopy,但也不起作用。返回的错误为

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)

但是,这并没有打开一个新的选项卡,只是移动到同一选项卡中的重定向页面。

如果没有简单的方法,我会创建一个列表或字典对象来存储我已经刮取的链接,每次刮取重定向页面后,我都会再次解析原始页面并跳过已经检查的链接。但我不想这样做,因为这是非常多余的。

共有3个答案

韩朝斑
2023-03-14

我能够使用类似这样的方法在改变页面的同时迭代元素(灵感来自于yong的答案)。

这将允许您保持索引循环遍历元素,而无需实际担心空引用。

    downloadList = driver.find_elements_by_id('download-form')
    
    for i in range(0, len(downloadList)):
        downloadList[i].submit()
        time.sleep(15)
        driver.get("url")
        time.sleep(5)
        downloadList = driver.find_elements_by_id('download-form')
        time.sleep(20)
袁宜
2023-03-14

我选择了一种方法来创建另一个网络驱动程序实例。

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()
逑景铄
2023-03-14

甚至你返回的是同一个页面,但是硒不知道是同一个页面,硒会把它当成一个新的页面。在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)
 类似资料:
  • 我在处理包含javascript链接的页面时遇到了麻烦。问题是页面包含的城市列表中有javascript在他们的链接。现在我必须一个接一个地导航到每个链接,抓取一些信息,然后回到列表,移动到下一个城市,继续抓取。 问题是在使用selenium web驱动程序点击javascript链接后,当我导航回列表页面时,响应丢失,我得到错误如下: 有办法吗?

  • 我正在使用Spring Security和前端reactJS的Spring Boot构建一个应用程序。我的代码可以很好地进行身份验证。但现在我计划将用户重定向到他以前请求的页面,以防他再次登录。 我可以从成功处理程序中提取 targetUrl,即上一页,但是当我在 UI 上执行控制台.log(数据)时。我得到的是原始的html数据而不是URL名称。我不知道为什么以及如何打开这样的原始 html 代

  • 本文向大家介绍vue页面跳转后返回原页面初始位置方法,包括了vue页面跳转后返回原页面初始位置方法的使用技巧和注意事项,需要的朋友参考一下 vue页面跳转到新页面之后,再由新页面返回到原页面时候若想返回调出原页面的初始位置,怎么来解决这个问题呢?首先我们应该在跳出页面时候记录下跳出的scrollY,返回原页面的时候在设置返回位置为记录下的scrolly即可,scrolly我用的是vuex状态管理器

  • 我正在开发一个应用程序,它允许用户浏览网站并从任何页面登录(登录链接位于公共标题中)。成功登录后,用户当前将从登录页面重定向到根url。 redirect_to原始页面会更友好。我试图将原始页面的命名路由存储到会话中,但这些似乎是对象,因此无法通过。此外,并非所有路由都带有指定的助手。另一方面,当我将文字路径作为字符串传递给redirect_to时,例如“订单/索引”,Rails将 /action

  • 使用父子 webview 或者同屏显示多个 webview 的性能和资源消耗较大。非必要不推荐使用同屏多 webview 的方案,推荐使用原生导航栏方案代替。可以加快窗体进入速度,内存占用更少。 通过在 mui.openWindow 的 styles 节点中设置 titleNView 节点的相关参数,可实现绘制原生导航栏控件,具体可参考 5+ webviewStyles 中的 titleNView

  • 我有一个运行多个应用程序的Tomcat 6服务器,在其中一个应用程序中,JSP指的是ColdFusion项目中的链接。在生产中,我们使用Apache设置将DocumentRoot更改为ColdFusion webroot,但是由于我们只运行Tomcat,所以我无法这样做(即,我们的系统没有httpd.conf或apache2.conf文件)。我尝试在一个上下文文件中设置一个docBase来指向Co