发送同时请求python(一次性全部)

joh*_*doe 4 python simultaneous-calls python-requests

我正在尝试创建一个脚本,同时向一个页面发送超过1000个请求.但是请求具有线程(1000)线程的库.似乎是在1秒内完成前50个左右的请求,而其他9950需要相当长的时间.我是这样测量的.

def print_to_cmd(strinng):
    queueLock.acquire()
    print strinng
    queueLock.release()

    start = time.time()
    resp = requests.get('http://test.net/', headers=header)
    end = time.time()

    print_to_cmd(str(end-start))
Run Code Online (Sandbox Code Playgroud)

我认为请求库限制了它们被发送的速度.

Doe的任何人都知道在python中同时发送请求的方式吗?我有一个200MB上传的VPS,所以这不是与python或请求库限制它的问题.他们都需要在1秒内互相访问网站.

感谢阅读,我希望有人可以提供帮助.

Eva*_*eri 11

我一般发现最好的解决方案是使用像龙卷风这样的异步库.然而,我发现最简单的解决方案是使用ThreadPoolExecutor.


import requests
from concurrent.futures import ThreadPoolExecutor

def get_url(url):
    return requests.get(url)
with ThreadPoolExecutor(max_workers=50) as pool:
    print(list(pool.map(get_url,list_of_urls)))
Run Code Online (Sandbox Code Playgroud)

  • @Enderphan 不,看看“map”是如何工作的:https://docs.python.org/3/library/functions.html#map ThreadPoolExecutor().map() 是同样的想法。 (2认同)

Mar*_*scu 10

我知道这是一个老问题,但您现在可以使用asyncioand来做到这一点aiohttp

import asyncio
import aiohttp
from aiohttp import ClientSession

async def fetch_html(url: str, session: ClientSession, **kwargs) -> str:
    resp = await session.request(method="GET", url=url, **kwargs)
    resp.raise_for_status()
    return await resp.text()

async def make_requests(url: str, **kwargs) -> None:
    async with ClientSession() as session:
        tasks = []
        for i in range(1,1000):
            tasks.append(
                fetch_html(url=url, session=session, **kwargs)
            )
        results = await asyncio.gather(*tasks)
        # do something with results

if __name__ == "__main__":
    asyncio.run(make_requests(url='http://test.net/'))
Run Code Online (Sandbox Code Playgroud)

您可以阅读有关它的更多信息并在此处查看示例。


lor*_*isi 1

假设您知道自己在做什么,我首先建议您实施带有抖动的退避策略,以防止您的服务器出现“可预测的雷霆囤积”。也就是说,你应该考虑做一些threading

import threading
class FuncThread(threading.Thread):
    def __init__(self, target, *args):
        self._target = target
        self._args = args
        threading.Thread.__init__(self)

    def run(self):
        self._target(*self._args)
Run Code Online (Sandbox Code Playgroud)

这样你就会做类似的事情

t = FuncThread(doApiCall, url)
t.start()
Run Code Online (Sandbox Code Playgroud)

你的方法 doApiCall 的定义如下

def doApiCall(self, url):
Run Code Online (Sandbox Code Playgroud)