【发布时间】:2021-07-11 23:12:51
【问题描述】:
我正在尝试使用 Python 和 Selenium 自动化 Space Invaders 的 www.freeinvaders.org 版本。实际游戏通过 HTML5 画布元素运行,该元素被包裹在 shadow-root 中。
使用this question 的答案,我正在尝试扩展 shadow-root,以便我可以单击画布并“玩”游戏。
我当前的代码:
def expand_shadow_element(element):
shadowRoot = browser.execute_script('return arguments[0].shadowRoot', element)
return shadowRoot
browser = webdriver.Firefox()
browser.get("http://www.freeinvaders.org/")
#wait for element to load
el = WebDriverWait(browser, timeout=20).until(lambda d:d.find_element_by_tag_name("ruffle-player"))
time.sleep(5)
#expand the shadowroot and click the canvas
host = browser.find_element_by_tag_name("ruffle-player")
shadowRoot = expand_shadow_element(host)
canvas = shadowRoot.find_element_by_tag_name("canvas")
canvas.click()
页面的HTML结构是这样的: (为便于阅读而删节)
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Free Invaders</title>
</head>
<body>
<div id='full-page-container'>
<main>
<div id="game-container">
<ruffle-player>
#shadow-root (open)
<div id="container" style="visibility: visible;">
<canvas width="1600" height="760" style="touch-action: none; cursor: auto;"></canvas>
</div><!--container-->
</ruffle-player>
</div><!--game-container-->
</div><!--fullpagecontainer-->
</body>
运行上述 Pyhton 脚本时,在这一行失败:
shadowRoot = browser.execute_script('return arguments[0].shadowRoot', element)
出现 Javascript 错误:
selenium.common.exceptions.JavascriptException: Message: Cyclic object value
我知道错误应该意味着返回的 JSON 字符串中有一个自引用项,但这里不应该是这种情况。
谁能帮助我解释为什么会出现这个错误以及采取什么行动可以缓解这个问题?
我正在使用 Python 3.8.5、Selenium 3.141.0 和 Firefox 86.0。所有这些都在 Linux Mint 20.1 上运行。
编辑 我还尝试了替代 Javascript:
shadowRoot = browser.execute_script('document.querySelector("ruffle-player").shadowRoot')
但这只会返回另一个错误:
AttributeError: 'NoneType' object has no attribute 'find_element_by_tag_name'
这表明它甚至没有找到任何对象。
【问题讨论】:
-
好吧,显然这在 Chrome 中确实有效,我在盯着它看了好几天后不情愿地安装了它。这有点虎头蛇尾,因为它不是我的代码有什么问题,而是(显然)是 Firefox 或 Geckodriver 中的一个错误。尽管如此,我将至少在赏金到期之前将这个问题保持开放,看看是否有人有专门针对 Firefox 的解决方案。
-
我无法访问您在我的笔记本电脑上共享的网页,因为我这边还有一些防火墙,但是您可以参考stackoverflow.com/questions/56380091/… 以了解 shadow-root 及其实施处理它们的选项。
-
谢谢,但这个答案虽然内容丰富,但最终指的是我已经在我的代码中实现的解决方案。正如我在上面的评论中所指出的,该解决方案适用于带有 Chromedriver 的 Chrome,但不适用于带有 Geckodriver 的 Firefox。
标签: javascript python selenium