在for循环中运行

问题描述 投票:0回答:1

我想在一个线程中的for循环中运行一个代码,因为它几乎会对不同的页面执行相同的操作(使用selenium webdriver)。我的问题是,我的计数器变量不能增加,因为它必须是最终的......

这是我的测试代码,但变量“tabCount”总是保持在i的计数。

// scrape over all tabs and get data in threads
        for (int i = 0; i < tabs.size(); i++) {
            final int tabCount = i;

            Runnable r = () -> {
                webDriver.switchTo().window(tabs.get(tabCount));
                System.out.println(webDriver.getTitle());
            };

            threadPool.execute(r);
        }

        threadPool.shutdown();
        try {
            threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

任何人都可以帮我在我的chromedriver的每个标签中并行执行相同的操作吗?

java selenium for-loop web-scraping selenium-chromedriver
1个回答
3
投票

我想你正在走错了兔子洞。看看你的代码:

webDriver.switchTo().window(tabs.get(tabCount));
System.out.println(webDriver.getTitle());

您希望webDriver切换到另一个窗口。然后在该选项卡上执行某些操作。但是如果第一行和第二行之间存在线程上下文切换怎么办?!

如:

  • 线程A:做webDriver.switchTo()
  • 线程B:做webDriver.switchTo()
  • 线程A:打印页面标题

显然这将导致竞争条件!当然,您可以添加某种锁定/同步,以便线程始终切换到选项卡并执行其工作,同时没有其他线程能够更新webDriver对象。但这基本上是序列化您的测试。

长话短说:webDriver对象有内部状态。您的方法完全忽略了这一事实,因此无法预测您的代码究竟会做什么。

一个简单的解决方法是按照注释中的建议为每个线程实例化一个WebDriver实例。除此之外,对于一个如何以不同方式做到这一点的想法,以一种与硒“思考”并行测试的方式相匹配的方式,请参阅here

© www.soinside.com 2019 - 2024. All rights reserved.