python - 1 个代理的 asyncio 中的信号量/多个池锁 - aiohttp

标签 python python-3.x python-asyncio aiohttp

我有 5,00,000 个网址。并希望异步获取每个响应。

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_list[:50] 但是如果我通过整个列表,我会得到这个错误

aiohttp.errors.ClientOSError: Cannot connect to host www.example.com:443 ssl:True Future/Task exception was never retrieved future: Task()

可能是频率太高了,服务器在限制后拒绝响应?

最佳答案

是的,可以预料到服务器在导致过多流量(无论“过多流量”的定义如何)后停止响应。

在这种情况下限制并发请求数量(限制它们)的一种方法是使用 asyncio.Semaphore ,类似于在多线程中使用的那些:就像在那里一样,您创建一个信号量并确保您想要限制的操作在进行实际工作之前获取该信号量并在之后释放它。

为了您的方便,asyncio.Semaphore实现上下文管理器以使其更容易。

最基本的方法:

CONCURRENT_REQUESTS = 200


@asyncio.coroutine
def worker(url, semaphore):
    # Aquiring/releasing semaphore using context manager.
    with (yield from semaphore):
        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

    semaphore = asyncio.Semaphore(CONCURRENT_REQUESTS)
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait([worker(u, semaphore) for u in url_list]))    

关于python - 1 个代理的 asyncio 中的信号量/多个池锁 - aiohttp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28406124/

相关文章:

Python 多维数组 - 计算非零条目数的最有效方法

python - Defaultdict/没有足够的值来解压

python-3.x - 在 Python 中打印扩展 ASCII 字符

python-3.x - 处理 python3 asyncio 中永不终止的任务

Python - 在 asyncio 中取消任务?

python - 为什么异步库比这个 I/O 绑定(bind)操作的线程慢?

python - 在 Django 中处理多个表行的表单(或 Formset?)

python - 使用具有外键关系的两个模型通过共享文本标签使用 QuerySet API 对 django 对象进行分组

python - if-else 理解字典在 python3 中不起作用

python - 通过python从名称列表中提取最后两个字母