這是一個兩部分問題。首先是你如何正確關閉與urllib2的連接?我見過很多例子,並且我採用了我能找到的最佳解決方案。但是,關閉文件似乎存在問題。如何關閉連接並重新使用urllib2連接?
目前我使用contextlib收盤()如下:
try:
with closing(self.opener.open(self.address,
None,
self.timeout)) as page:
self.data = page.read()
except:
# bail out..
然而,很長一段時間在OSX後,我仍然得到「太多打開文件」的錯誤。我使用ulimit將文件增加到2000以上。我還將內核的最大文件設置爲> 40,000。我應該注意到,這個方法所在的對象並沒有被處理掉,它仍然在程序的整個生命週期中。但是,我只保留存儲在對象中的「數據」以及地址和超時值。我不保存類似文件的對象。我認爲問題可能是引用,但我不這麼認爲,因爲我從不直接存儲對類文件對象的引用,只有read()中的數據。每次線程從隊列中拉出URL時,這些對象都會重新使用並重新加載新數據。
我一次只打開大約50個連接。我不太明白我如何用完文件。此外,當我用完文件的netstat開始使用malloc錯誤廢話了:
netstat(439) malloc: *** mmap(size=18446744073708605440) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
netstat: malloc 18446744073708605396 bytes: Cannot allocate memory
我還不能找到一種方法來重新連接,並得到netstat的恢復正常,而無需關閉。
的netstat -m
$ netstat -m
475/3803 mbufs in use:
475 mbufs allocated to data
3328 mbufs allocated to caches
407/3814 mbuf 2KB clusters in use
0/577 mbuf 4KB clusters in use
0/12 mbuf 16KB clusters in use
11242 KB allocated to network (8.3% in use)
0 requests for memory denied
0 requests for memory delayed
0 calls to drain routines
我無法定位的錯誤,但我相信在連接沒有及時關閉和連接時,我清楚地知道連接不上,甚至被重新使用到一個單一的域名(我希望那樣)。這是問題的第二部分。某人如何重用與urllib2的連接?
我有多個線程從隊列中獲取網址,每個線程都通過這種例程檢索數據。如果可能的話,我想重新使用連接,如果它已被另一個線程打開。線程之間共享的唯一數據是URL隊列。我查看了其他模塊,但他們似乎需要更多的數據共享,而不僅僅是一個url。
我將給出這個快速的一擊,看看我是否可以用請求替換urllib2的開啓者功能。我擔心的是與其他代碼的影響。我當然願意嘗試一下!謝謝 – 2012-04-01 04:26:24
我做了一些初步測試,看起來效果很好。我會花時間看看爬蟲是否死亡。我仍然對這個問題有更多的想法感興趣,所以我將在標記解決之前等待。 – 2012-04-01 04:37:54