Tij*_*men 2 javascript python selenium
我正在尝试使用 Python 和 Selenium 自动化www.freeinvaders.org版本的 Space Invaders。实际的游戏通过一个 HTML5 画布元素运行,该元素被包裹在一个 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()
Run Code Online (Sandbox Code Playgroud)
页面的 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>
Run Code Online (Sandbox Code Playgroud)
运行上面的 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')
Run Code Online (Sandbox Code Playgroud)
但这只会返回另一个错误:
AttributeError: 'NoneType' object has no attribute 'find_element_by_tag_name'
Run Code Online (Sandbox Code Playgroud)
这表明它甚至没有找到任何物体。
这似乎是bugzilla上提交的已知问题。
geckodriver 开发人员还表示 WebDriver 规范需要更新。请参阅:w3c/webdriver#350。
按照返回 Shadowroot 子级的建议,return arguments[0].shadowRoot.children它找到了 4 个元素:
[<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="1dd0fedf-1a8c-42f2-a4de-0ed7df478212", element="252a6352-4fe0-409d-a626-18456a973da5")>,
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="1dd0fedf-1a8c-42f2-a4de-0ed7df478212", element="47d76aed-5f44-4933-9718-53267a6417bf")>,
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="1dd0fedf-1a8c-42f2-a4de-0ed7df478212", element="d3fcad48-7cbb-4de3-a247-49d7d227e982")>,
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="1dd0fedf-1a8c-42f2-a4de-0ed7df478212", element="abb5012e-79bf-494b-b5f2-ff28dfecab0f")>]
Run Code Online (Sandbox Code Playgroud)
检查这些之后,看起来第三个元素包含画布并且可以单击。
以下代码似乎对我有用:
def expand_shadow_element(element):
# return a list of elements
shadowRoot = browser.execute_script('return arguments[0].shadowRoot.children', 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[2].find_element_by_tag_name("canvas")
canvas.click()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3003 次 |
| 最近记录: |