Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Selenium WebDriver快速分析大量链接集合_Javascript_Ruby_Selenium_Selenium Webdriver_Selenium Chromedriver - Fatal编程技术网

Javascript Selenium WebDriver快速分析大量链接集合

Javascript Selenium WebDriver快速分析大量链接集合,javascript,ruby,selenium,selenium-webdriver,selenium-chromedriver,Javascript,Ruby,Selenium,Selenium Webdriver,Selenium Chromedriver,我有一个网页有大量的链接(大约300),我想收集这些链接的信息 这是我的代码: beginning_time = Time.now #This gets a collection of links from the webpage tmp = driver.find_elements(:xpath,"//a[string()]") end_time = Time.now puts "Execute links:#{(end_time - beginning_time)*1000} millise

我有一个网页有大量的链接(大约300),我想收集这些链接的信息

这是我的代码:

beginning_time = Time.now
#This gets a collection of links from the webpage
tmp = driver.find_elements(:xpath,"//a[string()]")
end_time = Time.now
puts "Execute links:#{(end_time - beginning_time)*1000} milliseconds for #{tmp.length} links"


before_loop = Time.now
#Here I iterate through the links
tmp.each do |link|
    #I am not interested in the links I can't see
    if(link.location.x < windowX and link.location.y < windowY)
        #I then insert the links into a NoSQL database, 
        #but for all purposes you could imagine this as just saving the data in a hash table.
        $elements.insert({
            "text" => link.text,
            "href" => link.attribute("href"),
            "type" => "text",
            "x" => link.location.x,
            "y" => link.location.y,
            "url" => url,
            "accessTime" => accessTime,
            "browserId" => browserId
        })
    end
end
after_loop = Time.now
puts "The loop took #{(after_loop - before_loop)*1000} milliseconds"
start\u time=time.now
#这将从网页中获取链接集合
tmp=driver.find_元素(:xpath,“//a[string()]”)
结束时间=time.now
将“执行链接:{(结束时间-开始时间)*1000}毫秒用于{tmp.length}链接”
before\u loop=Time.now
#在这里,我遍历了这些链接
tmp.每个do |链接|
#我对看不到的链接不感兴趣
if(link.location.xlink.text,
“href”=>link.attribute(“href”),
“键入”=>“文本”,
“x”=>link.location.x,
“y”=>link.location.y,
“url”=>url,
“accessTime”=>accessTime,
“browserId”=>browserId
})
结束
结束
after_loop=Time.now
放置“循环时间为#{(在_循环之后-在_循环之前)*1000}毫秒”
目前,获取链接集合需要20毫秒,检索链接信息需要大约4000毫秒(或4秒)。当我将访问器从NoSQL插入中分离出来时,我发现NoSQL插入只需要20毫秒,而且大部分时间都花在访问器上(由于我不理解的原因,在与NoSQL插入分离后,访问器变得慢多了),这使我得出结论,访问器必须执行JavaScript

我的问题是:如何更快地收集这些链接及其信息?

想到的第一个解决方案是尝试并行运行两个驱动程序,但WebDriver不是线程安全的,这意味着我必须创建WebDriver的新实例并导航到页面。这就提出了一个问题,即如何下载页面的源代码,以便将其加载到另一个驱动程序中,而这在Selenium中是无法完成的,因此必须使用桌面自动化工具在Chrome本身上执行,从而增加了相当大的开销

我听说的另一种选择是停止使用ChromeDriver,只使用PhantomJS,但我需要在可视浏览器中显示页面


还有其他我没有考虑过的选择吗?

您似乎使用Webdriver纯粹是为了执行Javascript,而不是访问对象

如果您放弃使用javascript,可以尝试一些想法(请原谅java,但您明白了)

//我们通过xpath进行了限制,因此将获得更少的链接,并且不必检查循环中的文本
List linksWithText=driver.findElements(By.xpath(//a[text()和not(text()='')));
for(WebElement链接:linksWithText){
//存储位置详细信息,而不是每次重新获取
点位置=link.getLocation();
整数x=location.getX();
整数y=location.getY();
if(x

我通常使用远程网格,因此性能是我测试中的一个关键问题,因此为什么我总是试图通过CSS选择器或XPath进行限制,而不是获取所有内容并进行循环

您是否正在寻找驱动程序的替代方案。执行脚本(%{return document.links;})
?这并不是我代码中最慢的部分,但我仍然很好奇。是否存在替代方法?它是否更快?您可以使用类似的驱动程序-
。查找元素(:xpath,“//a”)
,以收集所有链接。我目前正在检查替代方法,并将在有确凿证据证明哪种方法更有效时返回。谢谢Robbie。我将运行一些基准测试并将它们添加到您的答案中。您介意详细介绍一下您的Xpath表达式吗?具体来说,
not(not(text())
完成了什么?因为它是双重否定的,所以可以用
text()
替换吗?最后,正如我在原始问题中提到的,当我试图将它们提取到临时变量而不是直接调用它们时,一切都变得慢了很多(正如你在回答中所建议的那样)。虽然Ruby不是你的首选语言,但你能想到这可能是什么原因吗?是的,你是对的,我只是很快地将它组装起来,并在Firepath中进行了测试。我已经删除了双NOTSo,那么这段代码在做什么?如果我理解的话,可能还可以写一个Ruby版本。。
 //We have restricted via xpath so will get less links back AND will not haveto check the text within loop
        List<WebElement> linksWithText = driver.findElements(By.xpath("//a[text() and not(text()='')]"));

        for (WebElement link : linksWithText) {

            //Store the location details rather than re-get each time
            Point location = link.getLocation();
            Integer x = location.getX();
            Integer y = location.getY();

            if (x < windowX && y < windowY) {
                ///Insert all info using webdriver commands;
            }
        }