使用2个线程WATIR RUBY控制相同的浏览器实例

时间:2018-01-03 14:15:54

标签: ruby multithreading watir

我希望我的程序能够不断检查元素是否正在呈现(总是检查它),但是当我尝试在另一个不同的线程中检查HTML时,我得到read_nonblock错误和/或流关闭错误(couldn&#39 ;在互联网上找到解释) 所以我创建了这个程序来验证wtf是否正在发生。

require 'watir'
require 'thread'

profile = Selenium::WebDriver::Firefox::Profile.new
profile['permissions.default.image'] = 2
profile['media.autoplay.enabled'] = false


browser = Watir::Browser.new :firefox, profile: profile
threads = Array.new
threads[0] = Thread.new do
  loop do
    begin
      sleep(3)
      puts browser.url
      browser.goto("https://monip.org")
    rescue
      puts "thread 1 encountered an error"
    end
  end
end
threads[1] = Thread.new do
  loop do
    begin
      if browser.url == "https://monip.org"
        puts "hi"
      end
    rescue
      puts "thread 2 encountered an error"
    end
  end
end

threads.each do |e|
  e.join
end

我得到

thread 1 encountered an error
thread 2 encountered an error
thread 2 encountered an error
thread 1 encountered an error
thread 1 encountered an error
about:blank
thread 2 encountered an error
thread 1 encountered an error
thread 1 encountered an error
thread 1 encountered an error
thread 2 encountered an error
thread 1 encountered an error
thread 2 encountered an error

当然,任何其他解决方案都会很好,这是我想要的,但无法用代码编写它。 是否可以使程序等待/检查它是否可以控制/与浏览器通信一段时间。 或保留浏览器一段时间我会使用" sleep"。 或允许2个线程立即控制浏览器。

编辑:通过使用"互斥"

,我能够获得理想的行为

这就是代码的外观

require 'watir'
require 'thread'

profile = Selenium::WebDriver::Firefox::Profile.new
profile['permissions.default.image'] = 2
profile['media.autoplay.enabled'] = false


mutex = Mutex.new
browser = Watir::Browser.new :firefox, profile: profile
threads = Array.new
threads[0] = Thread.new do
  loop do
  sleep(0.1)
    begin
      mutex.synchronize do
        puts "#{Time.now.ctime}  #{browser.url}"
        browser.goto("https://monip.org")
      end
    rescue
      puts "#{Time.now.ctime}  thread 1 encountered an error"
    end
  end
end

threads[1] = Thread.new do
  loop do
  sleep(0.1)
    begin
      mutex.synchronize do
        if browser.url == "https://monip.org/" || browser.url == "https://monip.org"
          puts "#{Time.now.ctime}  hi"
        end
      end
    rescue
      puts "#{Time.now.ctime}  thread 2 encountered an error"
    end
  end
end
threads[0].join
threads[1].join

输出

Fri Jan  5 13:49:36 2018  about:blank
Fri Jan  5 13:49:37 2018  hi
Fri Jan  5 13:49:37 2018  https://monip.org/
Fri Jan  5 13:49:37 2018  hi
Fri Jan  5 13:49:37 2018  https://monip.org/
Fri Jan  5 13:49:37 2018  hi
Fri Jan  5 13:49:37 2018  https://monip.org/
Fri Jan  5 13:49:38 2018  hi
Fri Jan  5 13:49:38 2018  https://monip.org/
Fri Jan  5 13:49:38 2018  hi
Fri Jan  5 13:49:38 2018  https://monip.org/
Fri Jan  5 13:49:38 2018  hi
Fri Jan  5 13:49:38 2018  https://monip.org/
Fri Jan  5 13:49:38 2018  hi
Fri Jan  5 13:49:38 2018  https://monip.org/
Fri Jan  5 13:49:39 2018  hi
Fri Jan  5 13:49:39 2018  https://monip.org/
Fri Jan  5 13:49:39 2018  hi
Fri Jan  5 13:49:39 2018  https://monip.org/
Fri Jan  5 13:49:39 2018  hi
Fri Jan  5 13:49:39 2018  https://monip.org/
Fri Jan  5 13:49:40 2018  hi
Fri Jan  5 13:49:40 2018  https://monip.org/
Fri Jan  5 13:49:40 2018  hi
Fri Jan  5 13:49:40 2018  https://monip.org/

正如您在时间戳中看到的那样,我们正在不断地检查并且不会引发任何错误

1 个答案:

答案 0 :(得分:1)

你根本无法让他们同时使用浏览器。

问题1:您的脚本永远不会输出" hi"因为网址实际上是" https://monip.org/",而不是" https://monip.org"。

问题2:你可能想要经常"检查这个元素(我假设某种对话或某种东西),因为一旦它出现,你就需要做一些事情。但通过不断检查,您基本上确保实际执行操作的线程将被中断。最有可能每秒检查一次(甚至2-10秒)就足够了。

问题3:正如我在开头所说,你不能让他们同时使用浏览器。您需要实现某种锁定过程以防止此行为。