có thể dễ dàng giới hạn tốc độ kbps khi sử dụng urllib2
không? Nếu có, bất kỳ ví dụ mã hoặc tài nguyên nào bạn có thể hướng dẫn tôi sẽ được đánh giá cao.Điều chỉnh với urllib2
10
A
Trả lời
19
Có chức năng urlretrieve(url, filename=None, reporthook=None, data=None)
trong mô-đun urllib
. Nếu bạn triển khai reporthook
-chức năng/đối tượng dưới dạng token bucket hoặc nhóm bị rò rỉ, bạn có giới hạn tốc độ toàn cầu của mình.
CHỈNH SỬA: Khi kiểm tra kỹ hơn Tôi thấy rằng không dễ dàng thực hiện giới hạn tốc độ toàn cầu với reporthook
như tôi nghĩ. reporthook
chỉ được cung cấp số tiền đã tải xuống và tổng kích thước mà chính chúng không đủ thông tin để sử dụng với nhóm mã thông báo. Một cách để vượt qua nó là lưu trữ số tiền được tải xuống lần cuối trong mỗi giới hạn tốc độ, nhưng sử dụng một nhóm mã thông báo toàn cục.
EDIT 2: Kết hợp cả hai mã thành một ví dụ.
"""Rate limiters with shared token bucket."""
import os
import sys
import threading
import time
import urllib
import urlparse
class TokenBucket(object):
"""An implementation of the token bucket algorithm.
source: http://code.activestate.com/recipes/511490/
>>> bucket = TokenBucket(80, 0.5)
>>> print bucket.consume(10)
True
>>> print bucket.consume(90)
False
"""
def __init__(self, tokens, fill_rate):
"""tokens is the total tokens in the bucket. fill_rate is the
rate in tokens/second that the bucket will be refilled."""
self.capacity = float(tokens)
self._tokens = float(tokens)
self.fill_rate = float(fill_rate)
self.timestamp = time.time()
self.lock = threading.RLock()
def consume(self, tokens):
"""Consume tokens from the bucket. Returns 0 if there were
sufficient tokens, otherwise the expected time until enough
tokens become available."""
self.lock.acquire()
tokens = max(tokens,self.tokens)
expected_time = (tokens - self.tokens)/self.fill_rate
if expected_time <= 0:
self._tokens -= tokens
self.lock.release()
return max(0,expected_time)
@property
def tokens(self):
self.lock.acquire()
if self._tokens < self.capacity:
now = time.time()
delta = self.fill_rate * (now - self.timestamp)
self._tokens = min(self.capacity, self._tokens + delta)
self.timestamp = now
value = self._tokens
self.lock.release()
return value
class RateLimit(object):
"""Rate limit a url fetch.
source: http://mail.python.org/pipermail/python-list/2008-January/472859.html
(but mostly rewritten)
"""
def __init__(self, bucket, filename):
self.bucket = bucket
self.last_update = 0
self.last_downloaded_kb = 0
self.filename = filename
self.avg_rate = None
def __call__(self, block_count, block_size, total_size):
total_kb = total_size/1024.
downloaded_kb = (block_count * block_size)/1024.
just_downloaded = downloaded_kb - self.last_downloaded_kb
self.last_downloaded_kb = downloaded_kb
predicted_size = block_size/1024.
wait_time = self.bucket.consume(predicted_size)
while wait_time > 0:
time.sleep(wait_time)
wait_time = self.bucket.consume(predicted_size)
now = time.time()
delta = now - self.last_update
if self.last_update != 0:
if delta > 0:
rate = just_downloaded/delta
if self.avg_rate is not None:
rate = 0.9 * self.avg_rate + 0.1 * rate
self.avg_rate = rate
else:
rate = self.avg_rate or 0.
print "%20s: %4.1f%%, %5.1f KiB/s, %.1f/%.1f KiB" % (
self.filename, 100. * downloaded_kb/total_kb,
rate, downloaded_kb, total_kb,
)
self.last_update = now
def main():
"""Fetch the contents of urls"""
if len(sys.argv) < 4:
print 'Syntax: %s rate url1 url2 ...' % sys.argv[0]
raise SystemExit(1)
rate_limit = float(sys.argv[1])
urls = sys.argv[2:]
bucket = TokenBucket(10*rate_limit, rate_limit)
print "rate limit = %.1f" % (rate_limit,)
threads = []
for url in urls:
path = urlparse.urlparse(url,'http')[2]
filename = os.path.basename(path)
print 'Downloading "%s" to "%s"...' % (url,filename)
rate_limiter = RateLimit(bucket, filename)
t = threading.Thread(
target=urllib.urlretrieve,
args=(url, filename, rate_limiter))
t.start()
threads.append(t)
for t in threads:
t.join()
print 'All downloads finished'
if __name__ == "__main__":
main()
Các vấn đề liên quan
- 1. Python urllib2 với giữ sống
- 2. Python Urllib2 Cookiejar với Selenium
- 3. Yêu cầu urllib2 sử dụng DNS tùy chỉnh
- 4. Tại sao tôi nhận được urllib2.HTTPError với urllib2 và không có lỗi với urllib?
- 5. Làm cách nào để gửi tiêu đề tùy chỉnh với urllib2 trong Yêu cầu HTTP?
- 6. Giao diện nguồn với Python và urllib2
- 7. Điều chỉnh băng thông trong Python
- 8. URL PythonLib/URLLib2 POST
- 9. Lỗi HTTP urllib2 429
- 10. urllib2 và json
- 11. AlphabetIndexer với Bộ điều hợp Tùy chỉnh
- 12. Lỗi Python urllib2
- 13. Caching trong urllib2?
- 14. urllib2 đọc to Unicode
- 15. Python: Urllib2 và OpenCV
- 16. Nhận URL khi xử lý urllib2.URLError
- 17. HTTPS đăng nhập bằng urllib2
- 18. suối lớn tập tin nhị phân với urllib2 nộp
- 19. Xử lý rss chuyển hướng với Python/urllib2
- 20. urllib2 python (Transfer-Encoding: chunked)
- 21. python urllib2 urlopen phản ứng
- 22. Python 3.2 Không thể nhập urllib2 (ImportError: Không có mô-đun tên urllib2)
- 23. Python: urllib/urllib2/httplib nhầm lẫn
- 24. urllib2.urlopen() vs urllib.urlopen() - urllib2 ném 404 trong khi urllib hoạt động! TẠI SAO?
- 25. điều chỉnh múi giờ
- 26. cách điều chỉnh mapred.reduce.parallel.copies?
- 27. Hiệu chỉnh điều chỉnh truy vấn Hive
- 28. Điều chỉnh Postgres
- 29. Điều chỉnh JSF
- 30. Điều khiển tùy chỉnh với ASP.NET MVC Razor
Cảm ơn bạn MizardX. Nó không phải là chính xác những gì tôi đang tìm kiếm như tôi cần một thực hiện cho urllib2 hơn là urllib, nhưng tôi nghĩ rằng điều này chắc chắn đã chỉ cho tôi đi đúng hướng. –
Chỉ cần thông tin: Tôi đã viết một hàm "read_limiting_rate()" chung có thể áp dụng cho tất cả các đối tượng có thể đọc được trong Python3. http://pastie.org/3120175 – Achimnol