python - 如何将密钥“发送”到画布元素更长的时间?
问题描述
我的目标:
我正在尝试制作一个 python 机器人来赢得chrome 的恐龙游戏。
游戏允许 2 种类型的跳跃:
- 短跳
- 跳远
使用main_body.send_keys(Keys.SPACE)
(如下面的代码所示)给出了短跳转。
我的问题:
我在执行跳远时遇到困难。
我的做法:
目前,对于跳远,我正在使用该Keyboard
库:
keyboard.press(keyboard.KEY_UP)
不幸的是,这需要浏览器窗口始终处于焦点位置。后来,我希望无头运行这个程序,所以这种方法行不通。
或者:
我试过ActionChains
:
ActionChains(driver) \
.key_down(Keys.SPACE) \
.pause(0.2) \
.key_up(Keys.SPACE) \
.perform()
但这最终会滚动整个页面。并且没有达到预期的目的。
我只是希望直接将这些动作“发送”到画布元素,而不是在整个页面上执行它们......
我想做这样的事情:
main_body.key_down(Keys.SPACE)
time.sleep(0.2)
main_body.key_up(Keys.SPACE)
虽然这当然会给我这个错误:AttributeError: 'FirefoxWebElement' object has no attribute 'key_down'
因为canvas
没有属性key_down
或key_up
.
这是一个 MCVE:
注意: 在代码中,恐龙会不断跳跃,但这不是重点,这只是为了检查跳跃的高度,而不是为了赢得比赛。
import keyboard
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
driver.get('https://chromedino.com/')
canvas = driver.find_element_by_css_selector('.runner-canvas')
main_body = driver.find_element_by_xpath("//html")
try:
canvas.click()
except:
main_body.send_keys(Keys.SPACE)
while True:
#short jump
main_body.send_keys(Keys.SPACE)
#long jump
ActionChains(driver) \
.key_down(Keys.SPACE) \
.pause(0.2) \
.key_up(Keys.SPACE) \
.perform()
#long jump using keyboard:
keyboard.press(keyboard.KEY_UP)
请为其他人注释掉代码,看看每种跳转的效果。
Keyboard
如果可能的话,建议一些其他的替代方法,在不使用和不滚动整个页面的情况下进行跳远......
解决方案
不幸的是,我看不到该游戏中跳跃的可重现行为。当我按 UP o SPACE 时,我随机看到短跳或长跳,所以我不能确定我的方法是否适合你。
但是,我认为,只需稍加努力,您就可以创建一个适合您需求的合适活动。基本上,由于 Selenium 可以执行任意 javascript,我的方法是向 canvas 元素发送一个 keydown 事件(使用 Firefox 77 测试)。
每次迭代都会制作一个屏幕截图,以确保恐龙实际跳跃。
玩得开心。
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
options = FirefoxOptions()
options.add_argument("--headless")
driver = webdriver.Firefox(options=options)
driver.get('https://chromedino.com/')
canvas = driver.find_element_by_css_selector('.runner-canvas')
main_body = driver.find_element_by_xpath("//html")
try:
canvas.click()
except:
main_body.send_keys(Keys.SPACE)
while True:
driver.execute_script('''
var keydownEvt = new KeyboardEvent('keydown', {
altKey:false,
altKey: false,
bubbles: true,
cancelBubble: false,
cancelable: true,
charCode: 0,
code: "Space",
composed: true,
ctrlKey: false,
currentTarget: null,
defaultPrevented: true,
detail: 0,
eventPhase: 0,
isComposing: false,
isTrusted: true,
key: " ",
keyCode: 32,
location: 0,
metaKey: false,
repeat: false,
returnValue: false,
shiftKey: false,
type: "keydown",
which: 32,
});
arguments[0].dispatchEvent(keydownEvt);
''', canvas)
driver.get_screenshot_as_file('proof_%s.png' % int(time.time()))
time.sleep(0.2)
driver.quit()
推荐阅读
- html - 使用 Jinja2 在每个 pdf 页面上重复页眉和页脚
- c - 在 C 中使用 return 和 putBack 函数递归地反转字符串
- azure - 将文件从 Azure Web 应用复制到 Azure 存储
- r - 如何从 R 中数据框中的行中删除模式?
- jdbc - 使用 pyspark 使用 JDBC 读取时使用 customSchema 的说明
- r - 随机选择行但有约束
- javascript - PWA React 无法加载页面
- docker - Docker for Windows 中的磁盘空间问题
- javascript - React 中的动态进度条
- bash - 从文件列表创建 Tar、Log 和 Zip 文件的脚本