PhantomJS使用过多的线程

问题描述 投票:7回答:3

我写了一个PhantomJS应用爬过一个网站,我建,并检查要包括JavaScript文件。 JavaScript的是类似于谷歌,其中一些行内代码加载在另一个JS文件。该应用程序会寻找其他的JS文件这就是为什么我用幻影。

什么是预期的结果?

控制台输出应该通过一吨的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对象仅仅是我已经抓取的网址的对象。该crawlURLs功能刚刚经历从getAllLinks功能的链接,并呼吁有抓取工具开始对域的基本域的所有链接打开的功能。

编辑

我修改了代码如下所示的最后一个块,但仍然有同样的问题。我已经加入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);
javascript web-crawler phantomjs
3个回答
6
投票

从文档:

由于一些技术上的限制,网页对象可能不是完全垃圾收集。当同一对象使用了一遍又一遍,这是经常遇到的。

解决的办法是显式调用close()网页的对象(即在许多情况下page)在正确的时间。

包括一些例子,如follow.js,表明有明确关闭多个页面对象。


4
投票

Open Files Limit.

即使正确关闭文件,你还是可能会遇到这个错误。

淘我发现了互联网络之后,你需要增加你的文件一个进程被允许具有开放的数量限制。就我而言,我是产生具有数百至数千页的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命令一个很好的参考,可以发现here

我希望,使一些人在正确的轨道上。


0
投票

我想出了这个错误,而在我的Ruby程序运行多个线程。我跑phantomjs与水豚,骚灵和每个线程访问了一个页面打开了相同的CSV文件,并写入到它。

我能够通过使用Mutex类来解决它。

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
© www.soinside.com 2019 - 2024. All rights reserved.