【问题标题】:Selenium webdriver multiple threadsSelenium webdriver 多线程
【发布时间】:2023-03-29 12:09:02
【问题描述】:

我有一个 winforms 项目,每当单击按钮时,它都会调用另一个使用 selenium 的类。我正在努力做到这一点,这样我就可以运行 1 - 无论我想运行多少个窗口。所以,我这样做是为了每当单击按钮时,它都会创建一个新线程并调用一个调用另一个类的方法。问题是每当我执行多个窗口时,似乎只有一个窗口在执行操作。所以如果我想要两个窗口来尝试选择一个国家,只有一个会选择一个国家。然而,两个窗口都打开了 url。我真的很困惑如何或为什么会发生这种情况,我在构造函数中初始化了一个新的 webdriver,所以我不明白为什么它似乎没有做任何其他事情。

using System;
using System.Threading;
using System.Windows.Forms;

namespace MRE
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(generate));
            t.IsBackground = true;
            t.Start();
           // if (!InvokeRequired)
           // {
           //     Invoke((Action)generate);
          //  }
        }

        private void generate()
        {
            
            Class1 generator = new Class1();
            generator.start();
        }
    }
}
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using System;
using System.Threading;

namespace MRE
{
    class Class1
    {
        public static IWebDriver driver;
        public static WebDriverWait wait;


        public Class1()
        {

            driver = new ChromeDriver();
            wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));


        }

        public void start()
        {
            try
            {
                driver.Navigate().GoToUrl("your url");

                //Input DOB


                SelectElement oSelect = new SelectElement(driver.FindElement(By.Id("capture-country")));
                Thread.Sleep(2000);
                oSelect.SelectByValue("GBR");
                //click
                wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("dob-field-inactive"))).Click();


                //enter Month
                wait.Until(ExpectedConditions.ElementIsVisible(By.Name("dob-month"))).SendKeys("01");
                Thread.Sleep(1000);
                //enter Day
                wait.Until(ExpectedConditions.ElementIsVisible(By.Name("dob-day"))).SendKeys("01");
                Thread.Sleep(1000);
                //enter Year
                wait.Until(ExpectedConditions.ElementIsVisible(By.Name("dob-year"))).SendKeys("2000");


            }

            catch (WebDriverException e)
            {
            }
        }
    }
}

【问题讨论】:

  • 您不能从另一个线程更新 GUI 线程。您是否尝试创建多个 GUI 线程(这比仅启动一个新线程要困难得多)? Application.DoEvents(); 是一个很大的代码味道,设计是 foobar。请注意,[STAThread](COM 承诺)和Application.Run 都用于正确创建初始 WinForms GUI 线程(消息泵等)。
  • 嗯,我添加线程的主要原因是为了使它在 Selenium 打开 chrome 时仍然可以使用 GUI。但问题是,当您单击该按钮两次时,它会打开两个 chrome 窗口并将您带到两个窗口上的 URL,但只有一个 chrome 驱动程序会选择该位置,而另一个只会遇到错误。我的问题不在于 GUI。
  • 你需要先修复generateGoogle。它正在访问 GUI 组件。您可以通过编组到 GUI 线程(Invoke、BeginInvoke、InvokeRequired)来使这些线程安全。你还提到了一个错误。有什么错误?另外,由于各种原因,我也不喜欢threader 方法。让我重新阅读您的问题,看看是否能找到更好的解决方案。
  • 访问 GUI 的线程安全方法是检查 InvokeRequired,如果是这样,则使用 InvokeBeginInvoke 来访问 GUI 线程。 Invoke 将阻塞直到完成,因此您可以从后台谷歌线程中使用它来访问 GUI 元素。这能解决你的问题吗?
  • 它抛出的错误是元素不可交互。我抓住了它,所以驱动程序不会崩溃,但我知道它是可交互的,因为另一个 chrome 窗口能够与选择项交互。我也试图更多地理解线程。听起来我正在使用的当前线程方法主要是面向 GUI 的线程?感谢您的帮助。

标签: c# multithreading winforms selenium google-chrome


【解决方案1】:

我实际上找到了解决这个问题的一种方法。我没有将 Webdriver 初始化为类变量,而是将其设置为 start() 方法的局部变量。它没有在我的 MRE 中显示,但在我的实际课程中,我有不同的方法使用驱动程序,所以我这样做了,所以我调用的任何方法的参数都包含 IWebDriver 作为参数。因此,没有一个 webdriver 实例在多个窗口中运行。如果有其他解决方法,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-27
    • 2011-11-23
    • 1970-01-01
    • 2018-05-29
    • 2017-11-25
    • 1970-01-01
    相关资源
    最近更新 更多