我正在使用Selenium浏览器进行日常浏览,当我按任意页面上的某些键时,我想要发送一些代码。起初我以为我可以在每个注册键/鼠标输入的页面上加载javascript,但实际上我真的更喜欢使用过去的键/鼠标点击提供一些python列表,例如我在javascript中的关键示例:
var myhistory = []
document.addEventListener("keydown", keyDownTextField, false);
function keyDownTextField(e) {
var keyCode = e.keyCode;
myhistory.push(keyCode)
}
有没有办法在纯Python / Selenium中做到这一点?
答案 0 :(得分:2)
我会尝试:
执行在文档正文中注册的javascript
<body onkeyup="my_javasctipt_keyup()" and onkeydown="my_javasctipt_keydown()">
使用browser.execute_script
。 (部分解决,见问题)
将密钥向上和keydown事件保存在javascript中的变量中。 (解决,见问题)
browser.execute_script
返回变量。我不确定:
browser.execute_script
的返回值可能只返回json可序列化对象或字符串希望这有帮助。如果任何代码结果形成,我会有兴趣知道。
这段代码是我觉得应该工作的:
from selenium import webdriver
browser = webdriver.Firefox()
browser.execute_script("""var myhistory = []
document.addEventListener("keydown", keyDownTextField, false);
function keyDownTextField(e) {
var keyCode = e.keyCode;
myhistory.push(keyCode)
}""")
def get_history():
return browser.execute_script("myhistory")
# now wait for a while and type on the browser
import time; time.sleep(5000)
print("keys:", get_history())
关键是selenium的代码永远不会在浏览器处理键盘输入的同时运行。因此,需要在javascript中处理事件,保存结果,例如在数组中然后,当询问selenium时,数组将返回到Python。
答案 1 :(得分:1)
boppreh/keyboard
会让你这样做。
你安装它。 pip install keyboard
你导入它。 import keyboard
你用吧。 keyboard.add_hotkey('left', print, args=['You pressed the left arrow key'])
然后你禁用它。 keyboard.remove_all_hotkeys()
答案 2 :(得分:0)
好吧,在这种情况下,您必须选择适合该工作的工具,我建议puppeteer一种Web自动化家庭工具纯洁的JS,可以轻松地与浏览器进行交互(从js到js) )并直接从另一端捕获事件,而无需任何中介。
使用硒,您仍然可以通过传递的方式实现此目的,而不会过多地干扰页面的代码,也不会因不必要的任务而过度使用它,而且重新加载页面内容会重置其所有变量,这意味着它是一种有损方法。最好的最接近方法是在内部设置一个事件处理程序,并直接使用Runtime.evaluate
从外部捕获它,因为它不会影响页面内容,并且特别地,它会坚持使用该函数,直到使用promise调用产生某些东西为止,这样最好而不是一遍又一遍地探索一些全局变量,这是一个不好的做法,请参见here。
myhistory = []
evt_handler = """
new Promise((rs,rj) => window.onkeydown= e => rs(e.keyCode) )
"""
def waitforclick():
try:
myhistory.append(browser.execute_cdp_cmd('Runtime.evaluate', {'expression': evt_handler, 'awaitPromise': True,'returnByValue': True})['result']['value'])
except:
waitforclick()
为避免锁定CPU,您需要并行派生一个线程。
from threading import Timer
t = Timer(0.0, waitforclick)
然后用t.start()
代替waitforclick()
。
如果您想在一段时间后以零值拒绝承诺,也可以使用timeout
。