Python aiohttp:在满足条件时取消异步执行
Python aiohttp: cancel async execution on met condition
我为 CTF 游戏编写了一个异步暴力破解脚本,如下所示
async def bound_fetch(sem, session, answer):
# generating url, headers and json ...
async with sem, session.post(url=url, json=json, headers=headers) as response:
if response.status == 200:
print('Right answer found: %s' % json['answer'])
async def run(words):
tasks = []
sem = asyncio.Semaphore(3)
async with aiohttp.ClientSession() as session:
for word in words:
task = asyncio.create_task(bound_fetch(sem=sem, session=session, answer=''.join(word)))
tasks.append(task)
print("Generated %d possible answers. Checking %s" % (len(tasks), base_url))
await asyncio.gather(*tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(run(possible_answers))
loop.run_until_complete(future)
我的参考是这个教程:https://pawelmhm.github.io/asyncio/python/aiohttp/2016/04/22/asyncio-aiohttp.html
我想知道这是否是在 aiohttp 中执行此操作的正确方法,还是我把事情弄得太复杂了(因为我不需要处理所有响应,只需要知道哪个响应的状态为 200)?如何在满足条件(状态码)时取消处理?
I was wondering if this is the right way to do it in aiohttp
您的代码相当地道。在顶层,您可以省略 asyncio.ensure_future
并简单地调用 asyncio.run(run(possible_answers))
.
How do I cancel the processing when the condition (status code) is met?
您可以使用事件或未来对象并等待它而不是使用 gather
。正如您可能知道的那样,运行 不需要 gather
协程(它们 运行 会尽快与 create_task
),它的明确目的是等待所有协程完成。基于 Event
的同步可能如下所示:
async def bound_fetch(sem, session, answer, done):
# generating url, headers and json ...
async with sem, session.post(url=url, json=json, headers=headers) as response:
if response.status == 200:
done.set()
done.run_answer = json['answer']
async def run(words):
sem = asyncio.Semaphore(3)
done = asyncio.Event()
async with aiohttp.ClientSession() as session:
tasks = []
for word in words:
tasks.append(asyncio.create_task(bound_fetch(
sem=sem, session=session, answer=''.join(word), done=done)))
print("Generated %d possible answers. Checking %s" % (len(words), base_url))
await done.wait()
print('Right answer found: %s' % done.run_answer)
for t in tasks:
t.cancel()
我为 CTF 游戏编写了一个异步暴力破解脚本,如下所示
async def bound_fetch(sem, session, answer):
# generating url, headers and json ...
async with sem, session.post(url=url, json=json, headers=headers) as response:
if response.status == 200:
print('Right answer found: %s' % json['answer'])
async def run(words):
tasks = []
sem = asyncio.Semaphore(3)
async with aiohttp.ClientSession() as session:
for word in words:
task = asyncio.create_task(bound_fetch(sem=sem, session=session, answer=''.join(word)))
tasks.append(task)
print("Generated %d possible answers. Checking %s" % (len(tasks), base_url))
await asyncio.gather(*tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(run(possible_answers))
loop.run_until_complete(future)
我的参考是这个教程:https://pawelmhm.github.io/asyncio/python/aiohttp/2016/04/22/asyncio-aiohttp.html
我想知道这是否是在 aiohttp 中执行此操作的正确方法,还是我把事情弄得太复杂了(因为我不需要处理所有响应,只需要知道哪个响应的状态为 200)?如何在满足条件(状态码)时取消处理?
I was wondering if this is the right way to do it in aiohttp
您的代码相当地道。在顶层,您可以省略 asyncio.ensure_future
并简单地调用 asyncio.run(run(possible_answers))
.
How do I cancel the processing when the condition (status code) is met?
您可以使用事件或未来对象并等待它而不是使用 gather
。正如您可能知道的那样,运行 不需要 gather
协程(它们 运行 会尽快与 create_task
),它的明确目的是等待所有协程完成。基于 Event
的同步可能如下所示:
async def bound_fetch(sem, session, answer, done):
# generating url, headers and json ...
async with sem, session.post(url=url, json=json, headers=headers) as response:
if response.status == 200:
done.set()
done.run_answer = json['answer']
async def run(words):
sem = asyncio.Semaphore(3)
done = asyncio.Event()
async with aiohttp.ClientSession() as session:
tasks = []
for word in words:
tasks.append(asyncio.create_task(bound_fetch(
sem=sem, session=session, answer=''.join(word), done=done)))
print("Generated %d possible answers. Checking %s" % (len(words), base_url))
await done.wait()
print('Right answer found: %s' % done.run_answer)
for t in tasks:
t.cancel()