我的数据抓取脚本都使用缓存来最小化服务器上的负载。请务必使用 HTTP 工具,例如“If-Modified-Since”、“If-None-Match”和“Accept-Encoding: gzip”。
还可以考虑使用多处理模块,以便您可以并行运行请求。
这是我的下载器脚本的摘录:
def urlretrieve(url, filename, cache, lock=threading.Lock()):
'Read contents of an open url, use etags and decompress if needed'
request = urllib2.Request(url)
request.add_header('Accept-Encoding', 'gzip')
with lock:
if ('etag ' + url) in cache:
request.add_header('If-None-Match', cache['etag ' + url])
if ('date ' + url) in cache:
request.add_header('If-Modified-Since', cache['date ' + url])
try:
u = urllib2.urlopen(request)
except urllib2.HTTPError as e:
return Response(e.code, e.msg, False, False)
content = u.read()
u.close()
compressed = u.info().getheader('Content-Encoding') == 'gzip'
if compressed:
content = gzip.GzipFile(fileobj=StringIO.StringIO(content), mode='rb').read()
written = writefile(filename, content)
with lock:
etag = u.info().getheader('Etag')
if etag:
cache['etag ' + url] = etag
timestamp = u.info().getheader('Date')
if timestamp:
cache['date ' + url] = timestamp
return Response(u.code, u.msg, compressed, written)
缓存是shelve的一个实例,一个持久字典。
对下载器的调用与多处理池实例上的 imap_unordered() 并行化。