使用Selenium打开新标签页并使用XPath抓取该标签页内容时出错

3

我正在使用Python中的Selenium。我有一些超链接列表,我正在迭代每个超链接,并在新标签页中打开该特定链接,然后使用Keys.CONTROL + Keys.SHIFT + Keys.RETURN将焦点放在新标签页上。

不幸的是,在新标签页上使用xpath选择时,打开新标签页失败:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from time import sleep  

list_links = self.driver(By.XPATH, "//a/" )
for link in list_links:
    link.send_keys(Keys.CONTROL + Keys.SHIFT + Keys.RETURN) #Open new Tab

    #get text from new tab webpage.
    sleep(50)
    data = self.driver.find_element(By.XPATH, "//span/" ).text #ERROR
    print data

我能够打开新的标签并设置焦点到新标签(这似乎有效)。但是当我尝试在新标签上使用XPath时,它会抛出:

NoSuchElementException: Message: no such element.

即使元素可用。我不知道我在这里做错了什么。任何帮助将不胜感激。


看起来你还停留在同一页,你在哪里切换页面? - Mahsum Akbas
@MahsumAkbas,我不这么认为。发送的键组合会打开一个新的选项卡,其中包含当前焦点下的链接。虽然我同意,在Selenium中测试是否正确工作是很好的。另外,请不要使用sleep(50)。不确定它是否会阻塞线程,但可能会,然后您将永远无法选择任何内容。请尝试使用WebDriverWait函数 - Abel
1
@Abel:我也尝试了WebDriverWait函数,但问题仍然存在。我认为问题在于链接在新标签页中打开,并且它显示当前标签页已聚焦,但我认为selenium将当前活动焦点指向了上一个标签页而不是当前标签页。请帮忙解决一下。 - iNikkz
在Windows中,您可以通过Ctrl+数字(选项卡的数量;1、2、3等)来切换选项卡。您可以尝试一下。 - Mahsum Akbas
@MahsumAkbas:我正在使用Linux。我找到了解决方案。我正在发布。感谢您的帮助。 - iNikkz
我去掉了你的内联加粗,因为它很难阅读。现在更加安静,干扰更少。对于未来的访问者也更好(太多的加粗通常被认为是“喊叫”,并不能帮助理解问题)。 - Abel
2个回答

2
以下代码是从此链接复制的,它展示了如何执行一些额外步骤来切换到另一个选项卡。请尝试:
browser = webdriver.Firefox()
browser.get('https://www.google.com?q=python#q=python')
first_result = ui.WebDriverWait(browser, 15).until(lambda browser: browser.find_element_by_class_name('rc'))
first_link = first_result.find_element_by_tag_name('a')

# Save the window opener (current window, do not mistaken with tab... not the same)
main_window = browser.current_window_handle

# Open the link in a new tab by sending key strokes on the element
# Use: Keys.CONTROL + Keys.SHIFT + Keys.RETURN to open tab on top of the stack 
first_link.send_keys(Keys.CONTROL + Keys.RETURN)

# Switch tab to the new tab, which we will assume is the next one on the right
browser.find_element_by_tag_name('body').send_keys(Keys.CONTROL + Keys.TAB)

# Put focus on current window which will, in fact, put focus on the current visible tab
browser.switch_to_window(main_window)

# do whatever you have to do on this page, we will just got to sleep for now
sleep(2)

# Close current tab
browser.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 'w')

# alternatively, use this, but it was reported that it doesn't always work
# driver.close()

# Put focus on current window which will be the window opener
browser.switch_to_window(main_window)

如果您使用的是Mac,可能无法正常工作,但在评论中也提供了解决方法。或者,这个SO答案有另一个解决方法,使用标签页的窗口名称。更新:如评论所述,用户使用Linux(不在OP中)。请使用以下键组合替代上面代码中提到的默认键组合:Keys.CONTROL + Keys.SHIFT + Keys.RETURN

first_link.send_keys(Keys.CONTROL + Keys.RETURN) and (Keys.CONTROL + 'w') and (Keys.CONTROL + 't')。在Linux中无法正常工作。因此,我使用Keys.CONTROL + Keys.SHIFT + Keys.RETURN来打开新标签页。我找到了解决方案。我正在发布...感谢您的帮助。 - iNikkz
@iNikkz:友情提示,在注释中使用 ```(反引号)代码,这样在您想要传达代码片段时,可以更加方便地让眼睛放松(粗体应该使用得非常谨慎,通常使用斜体更好)。 - Abel
谢谢。我会照顾好的。 - iNikkz

2
下面的代码是为了在新标签页中打开链接,并将焦点放在新打开的标签页上,然后从该新打开的标签页中获取XPATH。
#Set current_window_handle to main tab
main_tab = driver.current_window_handle

# Get all links
list_links = self.driver(By.XPATH, "//a/" )

#Iterate over links
for element in list_links:

  # Open link in new tab 
  link.send_keys(Keys.CONTROL + Keys.SHIFT + Keys.RETURN)

  # Switch focus to newly opened tab using driver.window_handles[1]
  # driver.window_handles[1] => [1] for new tab index.
  driver.switch_to_window(driver.window_handles[1])

  /*** Do something OR Grabbing content using XPATH ***/

  #Now close newly opened tab
  driver.close()

  #Again switch to main tab/ previous tab
  driver.switch_to_window(main_tab)

是的,那就是我发布的解决方案。如果是一样的话,你不应该重复发布。相反,如果你认为我打错了(我想你指的是send_keys),你可以随时编辑我的帖子或使用评论(就像你做的那样,谢谢)。 - Abel
@Abel:虽然 Ctrl+"t"Ctrl + "w" 不起作用,但我让它更简单了。请验证我的答案。 - iNikkz
啊,我明白你的意思了。这些键盘组合在不同的浏览器、系统甚至配置中可能会有所不同(例如,我的一些键盘组合就不同)。如果Selenium有一个“在标签页中打开”的命令,那就更好了,这将节省我们很多麻烦 ;)。 - Abel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接