[英]PhantomJS using too many threads
我寫了一個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對象只是我已經抓取的網址對象。 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()
(在許多情況下是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
命令的良好參考。
我希望這會讓一些人走上正軌。
我在ruby程序中運行多個線程時出現此錯誤。 我和Capybara-poltergeist一起運行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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.