我写了一个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);
从文档:
由于一些技术上的限制,网页对象可能不是完全垃圾收集。当同一对象使用了一遍又一遍,这是经常遇到的。
解决的办法是显式调用close()
网页的对象(即在许多情况下page
)在正确的时间。
包括一些例子,如follow.js,表明有明确关闭多个页面对象。
即使正确关闭文件,你还是可能会遇到这个错误。
淘我发现了互联网络之后,你需要增加你的文件一个进程被允许具有开放的数量限制。就我而言,我是产生具有数百至数千页的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。
我希望,使一些人在正确的轨道上。
我想出了这个错误,而在我的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