You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Selenium(Python)获取Canvas对象位置并点击它

解决Selenium中Canvas游戏对象的定位与点击问题

一、Canvas元素的特殊性说明

Canvas是浏览器中的绘图容器,内部的游戏对象都是通过JavaScript动态绘制的像素,并非DOM元素,因此Selenium无法直接通过常规的元素定位方法(如id、xpath)找到这些对象,必须通过坐标计算、图像识别或读取游戏内部数据的方式来实现点击。

二、解决方案

1. 基于相对坐标的直接点击

你已经获取了Canvas的位置和尺寸,接下来可以通过目标对象相对于Canvas左上角的偏移量来计算点击坐标:

  • 使用move_to_element_with_offset直接定位到Canvas内的相对位置
  • 或者先移动到Canvas,再通过move_by_offset调整位置

修改你的代码如下:

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep

driver = webdriver.Chrome()
driver.get("https://w55.sfgame.net/")
# 等待Canvas加载完成(建议后续替换为显式等待)
sleep(3)
canvas = driver.find_element("id", "canvas")

# 示例:点击Canvas内相对左上角(200, 300)的位置
action_chain = ActionChains(driver)
# 方法1:直接移动到Canvas的偏移位置
action_chain.move_to_element_with_offset(canvas, 200, 300).click().perform()

# 方法2:先移动到Canvas左上角,再偏移
# action_chain.move_to_element(canvas).move_by_offset(200, 300).click().perform()

sleep(5)
driver.quit()

2. 图像识别定位游戏对象(适合视觉可见的元素)

如果游戏对象的外观固定,可以通过截图匹配的方式找到其在Canvas内的坐标:

  1. 截取Canvas区域的截图
  2. 使用OpenCV或PIL匹配目标对象的模板图像
  3. 计算匹配到的坐标并执行点击

示例代码:

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import cv2
import numpy as np
from PIL import Image
from io import BytesIO
from time import sleep

driver = webdriver.Chrome()
driver.get("https://w55.sfgame.net/")
sleep(3)
canvas = driver.find_element("id", "canvas")

# 1. 截取Canvas截图
canvas_screenshot = canvas.screenshot_as_png
img = Image.open(BytesIO(canvas_screenshot))
img_np = np.array(img)

# 2. 加载目标对象的模板图像(提前保存游戏内目标的截图)
template = cv2.imread("target_object.png", 0)
img_gray = cv2.cvtColor(img_np, cv2.COLOR_BGR2GRAY)

# 3. 模板匹配
result = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8
locations = np.where(result >= threshold)

# 4. 点击第一个匹配到的位置
if len(locations[0]) > 0:
    # 取模板中心坐标作为点击点
    x = locations[1][0] + template.shape[1]//2
    y = locations[0][0] + template.shape[0]//2
    action_chain = ActionChains(driver)
    action_chain.move_to_element_with_offset(canvas, x, y).click().perform()

sleep(5)
driver.quit()

3. 注入JS读取游戏内部数据(如果游戏暴露了对象)

部分网页游戏会将游戏内对象的坐标等数据存储在全局变量中(如window.gameObjects),可以通过Selenium执行JS来获取这些数据:

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep

driver = webdriver.Chrome()
driver.get("https://w55.sfgame.net/")
sleep(3)
canvas = driver.find_element("id", "canvas")

# 执行JS获取游戏内目标对象的坐标(需根据实际游戏的变量名调整)
target_pos = driver.execute_script("""
    // 示例:假设游戏将玩家对象存在window.player中
    const player = window.player;
    return {x: player.x, y: player.y};
""")

# 计算Canvas内的点击坐标(需注意游戏的坐标系统是否与Canvas像素对应)
click_x = target_pos['x']
click_y = target_pos['y']

action_chain = ActionChains(driver)
action_chain.move_to_element_with_offset(canvas, click_x, click_y).click().perform()

sleep(5)
driver.quit()

注意事项

  • 若页面存在缩放或滚动,需先通过driver.execute_script("return window.devicePixelRatio")获取设备像素比,或调整滚动位置确保Canvas在视口中
  • 建议使用显式等待(WebDriverWait)替代sleep,确保Canvas和游戏资源加载完成
  • 部分游戏会检测自动化工具,可能需要添加反检测措施(如禁用自动化标志)

内容的提问来源于stack exchange,提问作者William Knutsson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 18:52:54