<分区>
想法很简单:我需要并行发送多个 HTTP 请求。
我决定使用 requests-futures库,它基本上产生了多个线程。
现在,我有大约 200 个请求,但速度仍然很慢(在我的笔记本电脑上大约需要 12 秒)。我还使用回调来解析响应 json(如库文档中所建议)。此外,是否有根据请求数确定最佳线程数的经验法则?
基本上,我想知道是否可以进一步加快这些请求的速度。
<分区>
想法很简单:我需要并行发送多个 HTTP 请求。
我决定使用 requests-futures库,它基本上产生了多个线程。
现在,我有大约 200 个请求,但速度仍然很慢(在我的笔记本电脑上大约需要 12 秒)。我还使用回调来解析响应 json(如库文档中所建议)。此外,是否有根据请求数确定最佳线程数的经验法则?
基本上,我想知道是否可以进一步加快这些请求的速度。
最佳答案
由于您使用的是 python 3.3,我将推荐一个仅限 python3 的 stdlib 解决方案:concurrent.futures
.
这是一个比直接处理 threading
或 multiprocessing
原语更高级的接口(interface)。您将获得一个 Executor
接口(interface)来处理池化和异步报告。
文档有一个例子,基本上可以直接适用于你的情况,所以我就把它放在这里:
import concurrent.futures
import urllib.request
URLS = #[some list of urls]
# Retrieve a single page and report the url and contents
def load_url(url, timeout):
conn = urllib.request.urlopen(url, timeout=timeout)
return conn.readall()
# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
# Start the load operations and mark each future with its URL
future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
try:
data = future.result()
# do json processing here
except Exception as exc:
print('%r generated an exception: %s' % (url, exc))
else:
print('%r page is %d bytes' % (url, len(data)))
如果您愿意,可以将 urllib.request
调用替换为 requests
调用。我确实更喜欢 requests
,原因很明显。
API 有点像这样:创建一组 Future
对象来表示函数的异步执行。然后,您可以使用 concurrent.futures.as_completed
为您提供一个遍历 Future
实例的迭代器。它会在它们完成时产生它们。
关于你的问题:
Also, is there a rule of thumb to figure out the optimal number of threads as a function of the number of requests, is there any?
根据经验,没有。这取决于太多因素,包括您的互联网连接速度。我会说这实际上并不取决于您的请求数量,更多取决于您运行的硬件。
幸运的是,调整 max_workers
kwarg 并自行测试非常容易。从 5 或 10 个线程开始,以 5 为增量增加。您可能会注意到性能在某个时候趋于平稳,然后开始下降,因为添加额外线程的开销超过了增加并行化的边际 yield (这是一个词) .
关于python - 在 Python 3 中发送多个 HTTP 请求的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20106621/