Python 1个代理的异步IO中的信号量/多个池锁-aiohttp
我有50万个网址。并希望以异步方式获取每个响应Python 1个代理的异步IO中的信号量/多个池锁-aiohttp,python,python-3.x,python-asyncio,aiohttp,Python,Python 3.x,Python Asyncio,Aiohttp,我有50万个网址。并希望以异步方式获取每个响应 import aiohttp import asyncio @asyncio.coroutine def worker(url): response = yield from aiohttp.request('GET', url, connector=aiohttp.TCPConnector(share_cookies=True, verify_ssl=False)) body = yield from response.
import aiohttp
import asyncio
@asyncio.coroutine
def worker(url):
response = yield from aiohttp.request('GET', url, connector=aiohttp.TCPConnector(share_cookies=True, verify_ssl=False))
body = yield from response.read_and_close()
print(url)
def main():
url_list = [] # lacs of urls, extracting from a file
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait([worker(u) for u in url_list]))
main()
我希望一次有200个连接(并发200个),因为
当我为50个url运行此程序时,它工作正常,即url\u list[:50]
但如果我通过了整个列表,我会得到这个错误
aiohttp.errors.ClientOSError: Cannot connect to host www.example.com:443 ssl:True Future/Task exception was never retrieved future: Task()
可能是频率太高,并且服务器在限制后拒绝响应?是的,可以预期服务器在对其造成过多流量(无论“过多流量”的定义如何)后会停止响应 在这种情况下,限制并发请求数量(限制它们)的一种方法是使用,与多线程中使用的方法类似:就像这里一样,创建一个信号量,并确保要限制的操作是在执行实际工作之前获取该信号量,然后再释放它 为方便起见,实现了上下文管理器,使其更加简单 最基本的方法:
CONCURRENT_请求=200
@异步协同程序
def工作者(url、信号量):
#使用上下文管理器获取/释放信号量。
带(信号量的产量):
响应=来自aiohttp.request的收益(
“得到”,
网址,
连接器=aiohttp.tcp连接器(共享=真,
验证(ssl=False))
body=响应的收益率。read_和_close()
打印(url)
def main():
url_list=[]#从文件中提取的一系列url
信号量=异步IO.semaphore(并发_请求)
loop=asyncio.get\u event\u loop()
loop.run_直到_完成(asyncio.wait([worker(u,信号量)在url_列表中表示u]))