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

时间:2016-11-03 00:19:30

标签: python python-requests simultaneous-calls

我尝试创建一个脚本,同时向一个页面发送超过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))

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

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

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

3 个答案:

答案 0 :(得分:8)

我一般发现最好的解决方案是使用龙卷风等异步库。然而,我发现最简单的解决方案是使用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)))

答案 1 :(得分:1)

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

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/'))

您可以阅读有关此内容的更多信息,并查看示例here

答案 2 :(得分:0)

假设你知道自己在做什么,我首先建议你实施一个带有抖动的退避策略,以防止可预测的雷鸣般的咆哮"到你的服务器。也就是说,你应该考虑做一些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)

这样你就可以做一些像

这样的事情
t = FuncThread(doApiCall, url)
t.start()

您的方法doApiCall定义如下

def doApiCall(self, url):