七大草 2023-07-14 14:12 采纳率: 100%
浏览 57
已结题

selenium自动化调用cmd打开页面后鼠标监听事件重复

遇到一个棘手的问题,如下:
在用selenium进行自动化操作时,使用pynput库进行监听鼠标的操作,监听鼠标点击事件,并同时判断点击的标签是否是想要点击的标签,根据标签内容选择调用不同浏览器打开该网址,打开网址的操作是使用os.system()打开的,这个时候再进行点击操作就会重复点击刚才点击的标签,不论点击哪里都会无限重复打开,下面是我的代码:
python代码如下:

import datetime
import os
import pytz
import subprocess
import pathlib

from selenium import webdriver
from pynput import *
from apscheduler.schedulers.background import BackgroundScheduler

folder = pathlib.Path(__file__).parent.resolve()
try:
  os.system("taskkill /f /t /im chromedriver.exe")
except:
  pass
options = webdriver.ChromeOptions()
options.add_experimental_option('detach', True)
options.add_argument('--disable-gpu')
driver = webdriver.Chrome(Options=options)
driver.get('file:///' + f'{folder}/abc.html')
driver.maximize_window()
js='''
  window.hovered_element = null
  function track_mouse(event){
    var x = event.clientX
    var y = event.clientY
    var element = document.elementFromPoint(x, y)
    if(!element){
      window.hovered_element = null
      return //当前页面没有元素
    }
    window.hovered_element = element
  }
  window.onmousemove = track_mouse
'''
driver.execute_script(js)

def cl():
  with mouse.Listener(on_click=on_click) as Listener:
    Listener.join()

def on_click(x, y, button, pressed):
  element_js = driver.execute_script('return window.hovered_element')
  if pressed:
    tag_name = element_js.tag_name
    if tag_name == 'a':
      _href = element_js.get_attribute("_href")
      _type = element_js.get_attribute("_type")
      if _type == 'Chrome':
        subprocess.Popen('"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" '+ _href)
      elif _type == 'IE':
        subprocess.Popen('"C:\\Program Files\\Internet Explorer\\iexplore.exe" '+ _href)
      elif _type == 'FireFox':
        subprocess.Popen('"C:\\Program Files\\Mozilla Firefox\\firefox.exe" '+ _href)

scheduler = BackgroundScheduler(timezone=pytz.timezone("Asia/Shanghai"))
scheduler.add_job(cl, 'date', next_run_time=datetime.datetime.now())
scheduler.start()

abc.html代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <div>
    <a _href="https://www.baidu.com" _type="Chrome">百度(使用Chrome打开)</a>
  </div>
  <div>
    <a _href="https://www.baidu.com" _type="IE">百度(使用IE打开)</a>
  </div>
</body>
</html>

目前使用cmd调用exe文件打开都没有问题,想实现一个页面循环调用监听鼠标事件打开(点完这个点那个,但是中间不会重复调用),想问各位这代码怎么修改可以实现呢,现在我只知道调用cmd后鼠标会停留在selenium自动化页面点击的那个标签上,切换到我用cmd打开的浏览器里再点击就会重复点击selenium刚才点击的那个标签

  • 写回答

7条回答 默认 最新

  • 技术宅program 2023-07-14 18:01
    关注

    你的鼠标监听器在执行完一次点击操作后没有正确地停止,而是继续监听鼠标事件,并且重复调用你的on_click函数。这样就会导致无限循环打开浏览器

    创建一个线程事件,你试下效果如何

    import datetime
    import os
    import pytz
    import subprocess
    import pathlib
    import threading # 导入threading模块
    
    from selenium import webdriver
    from pynput import *
    from apscheduler.schedulers.background import BackgroundScheduler
    
    folder = pathlib.Path(__file__).parent.resolve()
    try:
      os.system("taskkill /f /t /im chromedriver.exe")
    except:
      pass
    options = webdriver.ChromeOptions()
    options.add_experimental_option('detach', True)
    options.add_argument('--disable-gpu')
    driver = webdriver.Chrome(Options=options)
    driver.get('file:///' + f'{folder}/abc.html')
    driver.maximize_window()
    js='''
      window.hovered_element = null
      function track_mouse(event){
        var x = event.clientX
        var y = event.clientY
        var element = document.elementFromPoint(x, y)
        if(!element){
          window.hovered_element = null
          return //当前页面没有元素
        }
        window.hovered_element = element
      }
      window.onmousemove = track_mouse
    '''
    driver.execute_script(js)
    
    def cl():
      with mouse.Listener(on_click=on_click) as Listener:
        Listener.join()
    
    def on_click(x, y, button, pressed):
      element_js = driver.execute_script('return window.hovered_element')
      if pressed:
        tag_name = element_js.tag_name
        if tag_name == 'a':
          _href = element_js.get_attribute("_href")
          _type = element_js.get_attribute("_type")
          if _type == 'Chrome':
            subprocess.Popen('"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" '+ _href)
          elif _type == 'IE':
            subprocess.Popen('"C:\\Program Files\\Internet Explorer\\iexplore.exe" '+ _href)
          elif _type == 'FireFox':
            subprocess.Popen('"C:\\Program Files\\Mozilla Firefox\\firefox.exe" '+ _href)
          # 设置线程事件,通知主线程鼠标已经点击
          clicked.set()
          # 返回False,停止监听器
          return False
    
    # 创建一个线程事件对象
    clicked = threading.Event()
    
    while True: # 用一个循环来实现页面循环调用监听鼠标事件打开
      # 每次循环前清除线程事件状态
      clicked.clear()
      listener = mouse.Listener(on_click=on_click)
      listener.start()
      try:
        # 等待线程事件,直到鼠标点击为止
        clicked.wait()
      finally:
        # 停止监听器
        listener.stop()
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

问题事件

  • 系统已结题 7月23日
  • 已采纳回答 7月15日
  • 修改了问题 7月14日
  • 修改了问题 7月14日
  • 展开全部