这是脚本的精简版本,导致内存使用量不断增加,我看到它在2分钟后超过600MB:
import requests
import grequests
lines = (grequests.get(l.strip(), timeout=15) for l in open('links.txt') if len(l.strip()))
for r in grequests.imap(lines, size=20):
if r.ok:
print r.url
links.txt是一个包含大量网址的文件,问题出现在我收集的几个大网址组中。在我看来,响应对象可能没有被尊重?
我今天更新了gevent,请求和问候,这是他们的版本:
In [2]: gevent.version_info
Out[2]: (1, 0, 0, 'beta', 3)
In [5]: requests.__version__
Out[5]: '0.13.5'
grequests没有我能找到的版本号。
提前感谢您的任何答案。
答案 0 :(得分:0)
从我的角度来看,这是因为你试图同时打开所有链接。尝试这样的事情:
links = set(links)
while links:
calls = (grequests.get(links.pop()) for x in range(200))
for r in calls:
...rest of your code
此代码未经过测试,您会发现更好的解决方案,这应该证明您同时尝试打开太多链接并导致您的内存消耗。
答案 1 :(得分:0)
这个答案只是一个别名,可以链接回可能需要此link的人。
我使用imap函数和requests.Session来减少内存使用量,同时在我的脚本中发出380k请求。
答案 2 :(得分:0)
应该更新项目的请求库依赖项。
较旧版本的请求(包括在问题示例中使用的版本)在默认情况下不会预取任何响应内容,由您自己来使用数据。这样就留下了对基础套接字的开放引用,因此,即使请求会话是垃圾回收的,在响应超出范围或调用response.content
之前,也不会垃圾回收套接字。
在更高版本的请求中,默认情况下会预先提取响应,并且如果临时创建会话是为了满足模块级get
/ post
/ etc这样的请求,则会话将被明确关闭就像grequests在未传递会话时所做的一样。requests GitHub issue #520中对此进行了介绍。