我有一个包含大量链接(大约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"
目前需要20ms来获取链接,大约需要4000ms(或4秒)来检索链接的信息。当我将访问器与NoSQL插件分开时,我发现NoSQL插件只需要20ms,并且大部分时间花费在访问器上(由于我不明白的原因,它与NoSQL插件分离后变得慢得多) ),这使我得出结论,访问者必须执行JavaScript。
我的问题是:如何更快地收集这些链接及其信息?
首先想到的解决方案是尝试并行运行两个驱动程序,但WebDrivers不是线程安全的,这意味着我必须创建一个WebDriver的新实例并导航到该页面。这提出了一个问题,即如何下载页面源以便将其加载到另一个驱动程序中,这在Selenium中无法完成,因此必须使用桌面自动化工具在Chrome本身上执行,这会增加相当大的开销。 / p>
我听说的另一种选择是停止使用ChromeDriver并使用PhantomJS,但我需要在可视化浏览器中显示该页面。
还有其他我尚未考虑的替代方案吗?
答案 0 :(得分:1)
您似乎完全使用Webdriver来执行Javascript而不是访问对象。
如果您使用javascript删除,请尝试以下几种想法(请原谅java,但您明白了这一点);
//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;
}
}
我通常使用远程网格,因此性能是我测试中的一个关键问题,因此我总是试图通过CSS选择器或XPath来限制而不是获取所有内容并循环