Python 3.x 在使用python请求库时,是否有一些方法可以加速请求和/或timrout错误?

Python 3.x 在使用python请求库时,是否有一些方法可以加速请求和/或timrout错误?,python-3.x,optimization,python-requests,Python 3.x,Optimization,Python Requests,我正在做一项作业,用Python(3)使用HEAD方法向1000个特定网站发送请求(其中一些网站似乎已不存在),并报告有关其响应头的统计信息。剧本必须在五分钟内完成。显然,您可以通过减少超时使请求花费更少的时间,但是越是减少超时,超时错误就越多,捕获它们似乎非常昂贵。例如,当超时为0.3秒时,有700个良好请求和300个超时错误,捕获超时错误所花费的总时间本身大于5分钟。减少超时确实会减少捕获每个超时错误的时间,因为请求在抛出错误之前必须等待超时,但超时的数量也会增加。在timeout=0.05

我正在做一项作业,用Python(3)使用HEAD方法向1000个特定网站发送请求(其中一些网站似乎已不存在),并报告有关其响应头的统计信息。剧本必须在五分钟内完成。显然,您可以通过减少超时使请求花费更少的时间,但是越是减少超时,超时错误就越多,捕获它们似乎非常昂贵。例如,当超时为0.3秒时,有700个良好请求和300个超时错误,捕获超时错误所花费的总时间本身大于5分钟。减少超时确实会减少捕获每个超时错误的时间,因为请求在抛出错误之前必须等待超时,但超时的数量也会增加。在timeout=0.05和timeout=0.03时,我只能将捕获超时错误所花费的总时间控制在5分钟以下,但包括请求所花费时间在内的总时间仍然大于5分钟。超时=0.02导致只能访问20个站点,总错误处理时间为5:17,超时=0.01导致无法访问任何站点。分配任务的人坚持认为这是可能的,所以我一定是做错了什么。我尝试使用requests.Session对象,但这并没有导致任何明显的加速。我还能做些什么来加快速度呢?

真正的答案是使用异步HTTP请求。但为了合乎道德地回答这个问题,我必须坚持对每个域的同时请求设置一个较低的限制,否则会导致服务器过载(并被列入黑名单)

下面是一个使用
aiohttp
的(未经测试的)示例实现,它支持可配置的最大并行数以及每个域的最大并行数

导入aiohttp
导入异步
从收款进口柜台
并行数=64
每个域的最大并行数=4
TIMEOUT=aiohttp.ClientTimeout(总计=60)
异步def fetch_url(url,会话):
尝试:
以session.get(url)作为响应的异步:
#你要什么都行。
返回{
“url”:url,
“状态”:response.status,
“内容类型”:响应.标题[“内容类型”]
}
除了aiohttp.ServerTimeoutError之外:
返回{“url”:url,“status”:“timeout”}
例外情况除外,如e:
返回{“url”:url,“status”:“uncaught_exception”,“exception”:e}
域\数量\飞行中=计数器()
域_信号量={}
异步def工作程序(URL、结果):
与aiohttp.ClientSession异步(超时=超时)作为会话:
而URL:
url=url.pop()
domain=urlparse(url).netloc
如果域\u num\u飞行中[域]==0:
域信号量[domain]=asyncio.semaphore(每个域的最大并行信号量)
域数飞行中[域]+=1
与域\信号量[domain]异步:
results.append(等待获取url(url,会话))
域\u数量\u飞行中[域]-=1
如果domain_num_inflight[domain]==0:#防止内存泄漏。
del domain_信号量[域]
del domain_num_机上[域]
URL=[…]
工作列表=URL[:]
结果=[]
workers=[范围内(NUM_并行)的worker(工作列表,结果)]
loop=asyncio.get\u event\u loop()
循环。运行_直到_完成(asyncio.gather(*workers))
打印(结果)

是否允许/应该使用线程?一个简单的
concurrent.futures.ThreadPoolExecutor
可以用来并行化您的查询,这样您就不会被困在最慢的服务器上等待;它的
map
方法将使它变得非常简单。谢谢,我将查看这些库。如果我只点击每个URL一次(比如,给每个工作者分配一个完全不同的URL列表),是否需要信号量?@faiuwle重要的是,每个服务器只点击一次。例如,如果你的程序每秒多次从服务器请求内容,你可能会被列入黑名单(或者更糟,报告给执法部门)。不过,这些都是普通域,而且都是不同的-可以安全地假设不同的域不在同一台服务器上,对吗?@faiuwle不,但这“足够好”。如果您正在编写一个行业级状态检查器,您可能还包括一个单独的IP解析模块,并根据IP地址(块)执行更多的速率限制。当我使用loop.run_直到_完成(asyncio.gather(…)时),它立即超时。我甚至试着使用wait_for设置一个5分钟的特定超时,但它仍然会立即超时。是否有一些默认超时长度需要我以某种方式覆盖?