Python Selenium无法点击iframe内Canvas中的Play按钮
问题:Selenium无法点击iframe内Canvas中的Play按钮
在使用Python Selenium时,无法点击iframe内canvas.rendererView中的“Play”按钮。检查页面元素时,找不到与该按钮关联的明确DOM元素,只有当鼠标悬停在目标按钮上时,canvas的style属性会从cursor: inherit变为cursor: pointer。尝试切换iframe后通过偏移量点击的代码,但没有成功。
页面HTML代码
<iframe id="frameTest" class="trudyiframe" src="/trudydaily/game.phtml?id=1YHiRMqN9D7rpkR0iyA9FDJrdDhEc%2Bbj2v7hhLa%2FlpI%3D&slt=1&ver=2020" name="frameTest" frameborder="0" marginwidth="0" marginheight="0" scrolling="auto" onload="" allowtransparency="true"> <html><head> <title>Slots</title> <style> body { padding: 0; } .rendererView { margin: auto; display: block; width: 100%; height: auto; } #closeButton{ position:absolute; top:0; right:0; width:30; height:30; display: none; } @media screen and (max-width:576px) { div#trudyContainer iframe, div#tempcontent iframe{ height: 230px; } } </style> <script src="/trudydaily/js/lib/pixi.js"></script> <script> var slt_check_trudy = 1; </script> <script src="/trudydaily/js/game.js?v=20200806"></script> <script src="https://images.neopets.com/js/jquery-1.7.1.min.js" type="text/javascript"></script> <script> $( document ).ready(function() { // Note moved into ready var ajaxurl = '/trudydaily/ajax/claimprize.php'; var data = { 'action': 'getslotstate','key': '1YHiRMqN9D7rpkR0iyA9FDJrdDhEc%2Bbj2v7hhLa%2FlpI%3D'}; var resp; parent.$.post(ajaxurl, data, function (response) { resp = JSON.parse(response); if(resp.error == "") { SlotsGame.LoadAssets(AssetLoadComplete, "https://images.neopets.com"); } else { parent.CloseSlotsGame(); // @todo restore this 2020? } }); // 2020 H5 version: pass config object so we can switch context in game.js based on slt value. Original classic version included 3 different nearly duplicated .js files trudy_config = { "html5": "1", "slt_check_trudy": "1"}; SlotsGame.Initialize(trudy_config); function AssetLoadComplete(){ SlotsGame.Start(resp); } function CloseGame(){ parent.CloseSlotsGame(); //@todo restore this 2020 }; }); </script> <link href="chrome-extension://nffaoalbilbmmfgbnbgppjihopabppdk/inject.css" type="text/css" rel="stylesheet"></head> <body marginwidth="0" marginheight="0" class="vsc-initialized"><a href="#" onclick="parent.CloseSlotsGame();"> <img src="https://images.neopets.com/dailyslots/closebtn.png" id="closeButton"> </a> <canvas width="800" height="600" class="rendererView" style="cursor: inherit;"></canvas></body></html> </iframe>
测试代码
from selenium import webdriver from selenium.webdriver.support.select import Select from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains import time driver.get('https://www.neopets.com/trudys_surprise.phtml') time.sleep(4) iframeElement = driver.find_element(By.ID, "frameTest") driver.switch_to.frame("frameTest") time.sleep(2) action = webdriver.common.action_chains.ActionChains(driver) action.move_to_element_with_offset(iframeElement, 527, 672).click() time.sleep(30) driver.switch_to.default_content()
解决方案
你的代码核心问题有两个:一是偏移量的参考元素错误,二是没有等待游戏资源完全加载导致点击时机不对。以下是修正后的方案:
修正后的代码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver.get('https://www.neopets.com/trudys_surprise.phtml') # 等待iframe加载完成并切换进去,替代固定sleep WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "frameTest"))) # 等待canvas元素出现,并等待游戏加载完成(通过cursor状态判断按钮可点击) canvas = WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.CLASS_NAME, "rendererView"))) WebDriverWait(driver, 15).until(lambda d: canvas.value_of_css_property("cursor") == "pointer") # 以canvas为基准,点击Play按钮的相对偏移位置(需根据实际位置调整数值) action = ActionChains(driver) # 示例偏移量,你需要自己确认Play按钮在canvas内的准确坐标 action.move_to_element_with_offset(canvas, 400, 500).click().perform() driver.switch_to.default_content()
关键修正点
- 偏移参考元素修正:切换到iframe后,应该以内部的
canvas元素作为偏移基准,而不是主页面中的iframe元素——move_to_element_with_offset的偏移量是相对于目标元素左上角的,之前用iframe会导致坐标计算错误。 - 等待机制优化:用
WebDriverWait替代固定time.sleep,确保iframe和canvas加载完成,并且通过监控cursor属性确认Play按钮已经处于可交互状态,避免过早点击。 - 准确偏移量:你需要自己确认Play按钮在canvas内的准确坐标,可以通过浏览器开发者工具的元素定位功能,查看鼠标悬停在按钮上时的相对位置。
内容的提问来源于stack exchange,提问作者storyr4
相关产品推荐
相关产品推荐

