java - 我如何才能在 Java 中成功实现多线程 Selenium Server?

标签 java multithreading selenium

我正在尝试使用 selenium webdriver 作为查询/浏览器来设置生产者/消费者。

在运行以下代码时,并非所有查询都实际输入,即使输出显示它们是。一些查询也会加倍(即“Fish”变成“FisFishh”)。

应用

public class App {

    public static void main(String[] args) {

        DriverHashMap.init();

        Executor exec = new Executor();

        // Add queries to list
        Query query = new Query(exec);
        query.addQuery("Cats");
        query.addQuery("Dogs");
        query.addQuery("Fish");
        // query.addQuery("Bats");
        // query.addQuery("Rats");
        // query.addQuery("Geese");

        ExecutorService threadPool = Executors.newFixedThreadPool(4);

        // Submit queries to pool
        Future queryStatus = threadPool.submit(query);

        // Start browsers
        threadPool.execute(new Browser("1", exec));
        threadPool.execute(new Browser("2", exec));

        // this will wait for the producer to finish its execution.
        try {
            queryStatus.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        // Wait for pool to finish
        threadPool.shutdown();

    }
}

浏览器

public class Browser implements Runnable {
    private String name;
    private Executor exec;

    private static WebDriver driver;
    private static String baseURL = "http://www.google.com";
    private static String query;

    public Browser(String name, Executor exec) {

        synchronized (this) {
            this.name = name;
            this.exec = exec;

            System.out.println("\tStart Browser-" + this.name);
            driver = new FirefoxDriver();
            // Wait up to 30 seconds for a response
            driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

            DriverHashMap.addDriver(name, driver);
            System.out.println("\tAdded Browser-" + name + " to hashmap");
        }

    }

    private void enterQuery() {

        synchronized (this) {
            // Get driver for this browser
            driver = DriverHashMap.getDriver(this.name);
            System.out.println("Browser " + this.name
                    + " entering query from executor: " + query);

            // Search field qbqfq
            driver.findElement(By.id("gbqfq")).clear();

            // Enter query
            driver.findElement(By.id("gbqfq")).sendKeys(query);

            // Click search button
            driver.findElement(By.id("gbqfb")).click();
        }

    }

    public void run() {
        try {

            synchronized (this) {
                // Receive first query
                driver = DriverHashMap.getDriver(this.name);
                query = exec.get();
                System.out.println("Browser " + this.name
                        + "\n\rReceived first query from executor: " + query);
            }

            do {

                synchronized (this) {
                    // Process query
                    driver = DriverHashMap.getDriver(this.name);
                    driver.get(baseURL);
                    enterQuery();
                }

                synchronized (this) {
                    // Receive next query
                    query = exec.get();
                    driver = DriverHashMap.getDriver(this.name);
                    System.out.println("Browser " + this.name
                            + "\n\rReceived new query from executor: " + query);
                }

            } while (query != null);

            // Close this browser
            synchronized (this) {
                driver = DriverHashMap.getDriver(this.name);
                System.out.println("Browser " + this.name
                        + " finished its job; terminating.");

                driver.close();
            }

        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

}

查询

public class Query implements Runnable {
    private Executor exec;
    private List<String> queries = new ArrayList<String>();

    public Query(Executor exec) {
        this.exec = exec;
    }

    public void addQuery( String query ) {
        System.out.println("Adding " + query + " to queries");
        queries.add( query );
    }

    public void run() {

        Iterator it = queries.iterator();
        String currQuery = new String();

        try {
            while( it.hasNext()) {
                currQuery = (String)it.next();
                System.out.println("Adding " + currQuery + " to Executor");
                exec.put(currQuery);
            }

            this.exec.continueProducing = Boolean.FALSE;
            System.out.println("Query has finished its job; terminating.");
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

    }
}

执行者

public class Executor {
    public ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(
            100);
    public Boolean continueProducing = Boolean.TRUE;

    public void put(String query) throws InterruptedException {
        this.queue.put(query);
    }

    public String get() throws InterruptedException {
        return this.queue.poll(1, TimeUnit.SECONDS);
    }
}

最佳答案

Webdriver 本身不是线程安全的。尝试将其包装成 ThreadLocal .

这对我遇到类似情况帮助很大。

关于java - 我如何才能在 Java 中成功实现多线程 Selenium Server?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16283117/

相关文章:

python - 使用带有 Selenium 和 Python 的 headless 浏览器保存页面

java - 如何验证 JSoup 选择字符串

java - 静态方法重新定义规则

java - 微服务中的外部URL配置

java - 异步for循环没有挂起

selenium - 163 信息 : UPX is not available. Selenium pyinstaller 一个文件.exe

java - Google BigQuery 不稳定,几乎所有表查询都执行查询失败 : "Error: Error preparing subsidiary query: null"

java - 创建每 XXXXms 调用一个方法的计时器

java - 并发文件处理

python - Selenium Python - Webscraping Xpath 错误