如何关闭连接并重新使用urllib2连接?
问题描述:
这是一个两部分问题。首先是你如何正确关闭与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