python - 在 Python 3 中发送多个 HTTP 请求的最佳方式是什么?

标签 python multithreading http python-3.x concurrency

<分区>

想法很简单:我需要并行发送多个 HTTP 请求。

我决定使用 requests-futures库,它基本上产生了多个线程。

现在,我有大约 200 个请求,但速度仍然很慢(在我的笔记本电脑上大约需要 12 秒)。我还使用回调来解析响应 json(如库文档中所建议)。此外,是否有根据请求数确定最佳线程数的经验法则?

基本上,我想知道是否可以进一步加快这些请求的速度。

最佳答案

由于您使用的是 python 3.3,我将推荐一个仅限 python3 的 stdlib 解决方案:concurrent.futures .

这是一个比直接处理 threadingmultiprocessing 原语更高级的接口(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/

相关文章:

python - 如何检查浮点值是否为整数

python - 如何将 m2m 现场 session 从一个表单保存到另一个表单?

c# - 主进程在启动另一个线程后被卡住

c# - 线程、进程和 Application.Exit()

java - 如何使用notify/wait()唤醒/挂起特定(组)线程?

python - 提前停止使用 tensorflow tf.estimator ?

python - 如何向现有模型的每个模型字段添加新的 "comment"或 "flag"字段?

Python http.client getaddrinfo 失败

http - 如何在 Go 中执行 HTTP 双工处理程序?

java - 什么是可以拆分 http header 列表的最佳正则表达式?