Javascript 使用太多线程的PhantomJS

Javascript 使用太多线程的PhantomJS,javascript,web-crawler,phantomjs,Javascript,Web Crawler,Phantomjs,我编写了一个PhantomJS应用程序来爬过我构建的站点,并检查是否包含JavaScript文件。JavaScript类似于Google,其中一些内联代码加载到另一个JS文件中。该应用程序会查找另一个JS文件,这就是我使用Phantom的原因 预期结果是什么? 控制台输出应该读取大量URL,然后告诉脚本是否已加载 到底发生了什么事? 控制台输出将按预期读取大约50个请求,然后开始抛出此错误: 2013-02-21T10:01:23 [FATAL] QEventDispatcherUNIXPriv

我编写了一个PhantomJS应用程序来爬过我构建的站点,并检查是否包含JavaScript文件。JavaScript类似于Google,其中一些内联代码加载到另一个JS文件中。该应用程序会查找另一个JS文件,这就是我使用Phantom的原因

预期结果是什么?

控制台输出应该读取大量URL,然后告诉脚本是否已加载

到底发生了什么事?

控制台输出将按预期读取大约50个请求,然后开始抛出此错误:

2013-02-21T10:01:23 [FATAL] QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe
QEventDispatcherUNIXPrivate(): Unable to create thread pipe: Too many open files
这是打开页面并搜索脚本的代码块,包括:

page.open(url, function (status) {
    console.log(YELLOW, url, status, CLEAR);
    var found =  page.evaluate(function () {
      if (document.querySelectorAll("script[src='***']").length) {
        return true;
      } else { return false; }
    });

    if (found) {
      console.log(GREEN, 'JavaScript found on', url, CLEAR);
    } else {
      console.log(RED, 'JavaScript not found on', url, CLEAR);
    }
    self.crawledURLs[url] = true;
    self.crawlURLs(self.getAllLinks(page), depth-1);
  });
crawledURLs对象只是我已经爬网过的URL对象。crawlURLs函数只是遍历getAllLinks函数中的链接,并对具有爬虫程序启动所在域的基本域的所有链接调用open函数

编辑

我将代码的最后一块修改如下,但仍然存在相同的问题。我已经在文件中添加了page.close()

if (!found) {
  console.log(RED, 'JavaScript not found on', url, CLEAR);
}
self.crawledURLs[url] = true;
var links = self.getAllLinks(page);
page.close();
self.crawlURLs(links, depth-1);

从文件中:

由于某些技术限制,web页面对象可能不会完全被垃圾收集。当重复使用同一对象时,经常会遇到这种情况

解决方案是在正确的时间显式调用网页对象的
close()

其中的一些示例,例如,演示了具有显式关闭的多个页面对象。

打开文件限制。 即使正确关闭文件,也可能会遇到此错误

在浏览互联网之后,我发现您需要增加单个进程允许打开的文件数限制。在我的例子中,我生成了数百到数千页的PDF

根据您正在运行的系统,有不同的方法调整此设置,但以下是在Ubuntu服务器上对我有效的方法:

将以下内容添加到
/etc/security/limits.conf
的末尾:

# Sets the open file maximum here.
# Generating large PDFs hits the default ceiling (1024) quickly. 
*    hard nofile 65535
*    soft nofile 65535
root hard nofile 65535 # Need these two lines because the wildcards (above)
root soft nofile 65535 # are not applied to the root user as well.
可以找到
ulimit
命令的良好参考


我希望这能让一些人走上正轨。

我在ruby程序中运行多个线程时遇到了这个错误。 我用水豚怪运行phantomjs,每个线程访问一个页面,打开同一个CSV文件并写入

我可以通过使用
互斥锁
类来修复它

lock = Mutex.new
lock.synchronize do
    CSV.open("reservations.csv", "w") do |file|
        file << ["Status","Name","Res-Code","LS-Num","Check-in","Check-out","Talk-URL"]
          $status.length.times do |i|
              file << [$status[i],$guest_name[i],$reservation_code[i],$listing_number[i],$check_in[i],$check_out[i], $talk_url[i]]
          end
        end
        puts "#{user.email} PAGE NUMBER ##{p+1} WRITTEN TO CSV"
    end
end
lock=Mutex.new
同步锁
打开(“reservations.CSV”,“w”)do |文件|

我尝试在
self.crawlURLs()
之后调用页面关闭文件,但得到一个错误,页面中未定义关闭。实际错误是
TypeError:“undefined”不是函数(计算“page.close()”)
您可以忽略最后一条注释。我在一个旧版本的幻影。我重构了上面的代码,但仍然存在同样的问题。如果没有一个完整的可复制测试用例,那么调试就不容易了。我将尝试为它准备一个可行的测试用例,但是,如果你做了任何事情,在PhantomJS中生成了一堆网页,那么你就会看到这个问题。不久前我遇到了一个类似的问题,这个解决方案成功了。它应该被标记为正确答案。如果您正在使用类似Unix的操作系统,
ulimit-Sn
会说什么?在MacOSX上,默认值是256,这相当低。我在Ubuntu上,上面写着1024。好的,应该足够了。