我有一个包含大量链接(大约 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"
目前获取链接集合需要 20 毫秒,检索链接信息大约需要 4000 毫秒(或 4 秒)。当我将访问器与 NoSQL 插入分开时,我发现 NoSQL 插入只需要 20 毫秒,并且大部分时间都花在了访问器上(与 NoSQL 插入分开后,访问器变得慢得多,原因我不明白),这使我得出结论,访问器必须正在执行 JavaScript。
我的问题是:如何更快地收集这些链接及其信息?
想到的第一个解决方案是尝试并行运行两个驱动程序,但 WebDriver 不是线程安全的,这意味着我必须创建 WebDriver 的新实例并导航到页面。这就提出了一个问题,如何下载页面的源代码以便将其加载到另一个驱动程序中,这在 Selenium 中无法完成,因此必须使用桌面自动化工具在 Chrome 本身上执行,增加了相当大的开销。
我听说的另一种选择是停止使用 ChromeDriver 并只使用 PhantomJS,但我需要在可视浏览器中显示页面。
还有其他我还没有考虑过的选择吗?