Python asyncio/aiohttp:ValueError:Windows上select()中的文件描述符太多

2024-10-01 09:22:04 发布

您现在位置:Python中文网/ 问答频道 /正文

在 大家好, 我在尝试理解asyncio和aiohttp并使它们正常工作时遇到了困难。我不仅不明白我在做什么,而且在这一点上我遇到了一个我不知道如何解决的问题。在

我正在使用Windows 10 64位最新更新。在

下面的代码使用asyncio返回一个页面列表,这些页面的内容类型中不包含html。在

import asyncio
import aiohttp

MAXitems = 30

async def getHeaders(url, session, sema):
    async with session:
        async with sema:
            try:
                async with session.head(url) as response:
                    try:
                        if "html" in response.headers["Content-Type"]:
                            return url, True
                        else:
                            return url, False
                    except:
                        return url, False
            except:
                return url, False


def checkUrlsWithoutHtml(listOfUrls):
    headersWithoutHtml = set()
    while(len(listOfUrls) != 0):
        blockurls = []
        print(len(listOfUrls))
        items = 0
        for num in range(0, len(listOfUrls)):
            if num < MAXitems:
                blockurls.append(listOfUrls[num - items])
                listOfUrls.remove(listOfUrls[num - items])
                items +=1
        loop = asyncio.get_event_loop()
        semaphoreHeaders = asyncio.Semaphore(50)
        session = aiohttp.ClientSession()
        data = loop.run_until_complete(asyncio.gather(*(getHeaders(url, session, semaphoreHeaders) for url in blockurls)))
        for header in data:
            if False == header[1]:
                headersWithoutHtml.add(header)
    return headersWithoutHtml


listOfUrls = ['http://www.google.com', 'http://www.reddit.com']
headersWithoutHtml=  checkUrlsWithoutHtml(listOfUrls)

for header in headersWithoutHtml:
    print(header[0])

在 当我使用2000个URL(有时)运行它时,它会返回如下内容:

^{pr2}$

注1:我在用户中编辑了用户名。在

注2:出于任何原因reddit.com网站返回,因为它不包含HTML,这是一个完全独立的问题,我将尝试解决,但是如果你注意到我的代码中有其他不一致的地方,请指出它。在

注意3:我的代码构造得很糟糕,因为我尝试过改变很多东西来调试这个问题,但是我没有运气。在

我在某个地方听说这是对Windows的限制,没有办法绕过它,问题是:

a)我直接不明白“select()中的文件描述符太多”是什么意思。在

b)我做了什么Windows无法处理的错误?我见过有人用asyncio和aiohttp推送数千个请求,但是即使使用我的chunking,我也不能在没有值错误的情况下推30-50?在

编辑:在MAXitems=10的情况下,它还没有让我崩溃,但因为我不能遵循模式,我不知道为什么或如何告诉我任何事情。在

Edit2:不必担心,它需要更多的时间来崩溃,但即使MAXitems=10,它最终还是崩溃了


Tags: inasynciofalseurlforasyncreturnaiohttp
2条回答

默认情况下,Windows在asyncio循环中只能使用64个套接字。这是底层select()API调用的限制。在

要增加限制,请使用ProactorEventLoop。安装说明见here。在

我也有同样的问题。不能百分之百地确定它能正常工作,但请尝试替换它:

session = aiohttp.ClientSession()

有了这个:

^{pr2}$

默认情况下,limit设置为100(docs),这意味着客户端一次可以同时打开100个连接。正如Andrew提到的,Windows一次只能打开64个套接字,所以我们提供一个小于64的数字。在

相关问题 更多 >