# ValueError: too many file descriptors in select()错误和解决

ValueError: too many file descriptors in select()的原因

因为asyncio内部用到了select,而select就是系统打开文件数是有限度的,,这个其实是操作系统的限制,linux打开文件的最大数默认是1024,windows默认是509,超过了这个值,程序就开始报错,
下面的代码一次性将处理url的函数作为任务扔进了一个超大的List中,这就引起了错误。

我最初出错在于windows系统中asyncio爬虫测试中:

import aiohttp
import asyncio

num = 0

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main(url):
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, url)
        global num
        num += 1
        print('------------{}'.format(num))
        # print(html)

#asyncio 高并发库
def tasks():
    task = list()
    for i in range(114499,120000):
        # 114499 http://blog.jobbole.com/114499/
        task.append(main("http://blog.jobbole.com/{}/".format(i)))
    return task


loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks()))

解决:

如下面的代码。限制并发量, semaphore = asyncio.Semaphore(500) async with semaphore:
#Windows在500以下。

#coding:utf-8
import time,asyncio,aiohttp
				#aiohttp则是基于asyncio实现的HTTP框架。
				#asyncio 协程并发模块
num = 0

async def fetch(session,url):
    async with session.get(url) as response:	  #session.get(url)获取页面
        return await response.text()		#返回页面解码后的信息

async def main(url,semaphore):
    async with semaphore:		#这里进行执行asyncio.Semaphore,
        async with aiohttp.ClientSession() as session:  创建了一个命名为session的aiohttp.ClientSession 对象
            html = await fetch(session, url)		#相当于 yield from 
            global num
            num += 1
            print(html)
            print('------------{}'.format(num))


async def run():
    semaphore = asyncio.Semaphore(500)		 # 限制并发量为500,这里windows需要进行并发限制,
    						#不然将报错:ValueError: too many file descriptors in select()

    to_get = [main("http://blog.jobbole.com/{}/".format(_),semaphore) for _ in range(114364,120000)]
    																 #总共1000任务
    await asyncio.wait(to_get)
    
    #Python中对于无需关注其实际含义的变量可以用_代替,这就和for i in range(5)一样,因为这里我们对i并不关心,所以用_代替仅获取值而已。


if __name__ == '__main__':
#    now=lambda :time.time()
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())
    loop.close()
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值