我尝试创建一个脚本,同时向一个页面发送超过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秒之内到达网站。
感谢阅读,我希望有人可以提供帮助。
答案 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)
我知道这是一个老问题,但是您现在可以使用asyncio
和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/'))
您可以阅读有关此内容的更多信息,并查看示例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):