在Python Selenium中检测用户密钥/鼠标

时间:2015-03-05 22:53:26

标签: javascript python selenium

我正在使用Selenium浏览器进行日常浏览,当我按任意页面上的某些键时,我想要发送一些代码。起初我以为我可以在每个注册键/鼠标输入的页面上加载javascript,但实际上我真的更喜欢使用过去的键/鼠标点击提供一些python列表,例如我在javascript中的关键示例:

var myhistory = []

document.addEventListener("keydown", keyDownTextField, false);

function keyDownTextField(e) {
var keyCode = e.keyCode;
  myhistory.push(keyCode)
}

有没有办法在纯Python / Selenium中做到这一点?

3 个答案:

答案 0 :(得分:2)

我会尝试:

  1. 执行在文档正文中注册的javascript

    <body onkeyup="my_javasctipt_keyup()" and onkeydown="my_javasctipt_keydown()"> 
    

    使用browser.execute_script。 (部分解决,见问题)

  2. 将密钥向上和keydown事件保存在javascript中的变量中。 (解决,见问题)

  3. 使用browser.execute_script返回变量。
  4. 我不确定:

    • browser.execute_script的返回值可能只返回json可序列化对象或字符串
    • 如果在定义自己的事件侦听器的子元素中使用
    • 正文中的keyup和keydown可能无法正常工作

    希望这有帮助。如果任何代码结果形成,我会有兴趣知道。

    这段代码是我觉得应该工作的:

    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