hziwei

前言

aiohttp是一个为Python提供异步HTTP 客户端/服务端编程,基于asyncio(Python用于支持异步编程的标准库)的异步库。
aiohttp强调的是异步并发。提供了对asyncio/await的支持,可以实现单线程并发IO操作。

python异步aiohttp和同步requests

  • 下面以爬取豆瓣top250为例
    requests抓取:
import requests
headers = {
    \'user-agent\': \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36\',
}
start = time.time()
for page in range(0, 250, 25):
    data = requests.get(f"https://movie.douban.com/top250?start=0", headers=headers)
    html = etree.HTML(data.text)
    title_list = html.xpath(\'//div[@class="item"]/div/a/img/@alt\')
    print(title_list)

end = time.time()

print(f"Time consuming:{end -start}")

执行结果:最终消耗时间是1.7s左右

[\'肖申克的救赎\', \'霸王别姬\', \'阿甘正传\', \'这个杀手不太冷\', \'美丽人生\', \'泰坦尼克号\', \'千与千寻\', \'辛德勒的名单\', \'盗梦空间\', \'忠犬八公的故事\', \'海上钢琴师\', \'楚门的世界\', \'三傻大闹宝莱坞\', \'机器人总动员\', \'放牛班的春天\', \'星际穿越\', \'大话西游之大圣娶亲\', \'熔炉\', \'疯狂动物城\', \'无间道\', \'龙猫\', \'教父\', \'当幸福来敲门\', \'怦然心动\', \'触不可及\']
[\'蝙蝠侠:黑暗骑士\', \'控方证人\', \'活着\', \'乱世佳人\', \'寻梦环游记\', \'末代皇帝\', \'摔跤吧!爸爸\', \'指环王3:王者无敌\', \'何以为家\', \'少年派的奇幻漂流\', \'飞屋环游记\', \'十二怒汉\', \'鬼子来了\', \'天空之城\', \'哈尔的移动城堡\', \'大话西游之月光宝盒\', \'素媛\', \'天堂电影院\', \'罗马假日\', \'闻香识女人\', \'辩护人\', \'哈利·波特与魔法石\', \'搏击俱乐部\', \'我不是药神\', \'死亡诗社\']
[\'教父2\', \'指环王2:双塔奇兵\', \'狮子王\', \'窃听风暴\', \'大闹天宫\', \'指环王1:魔戒再现\', \'两杆大烟枪\', \'美丽心灵\', \'猫鼠游戏\', \'饮食男女\', \'飞越疯人院\', \'黑客帝国\', \'钢琴家\', \'V字仇杀队\', \'本杰明·巴顿奇事\', \'看不见的客人\', \'让子弹飞\', \'西西里的美丽传说\', \'小鞋子\', \'拯救大兵瑞恩\', \'海豚湾\', \'情书\', \'穿条纹睡衣的男孩\', \'音乐之声\', \'绿皮书\']
[\'美国往事\', \'海蒂和爷爷\', \'致命魔术\', \'低俗小说\', \'七宗罪\', \'沉默的羔羊\', \'蝴蝶效应\', \'春光乍泄\', \'禁闭岛\', \'心灵捕手\', \'被嫌弃的松子的一生\', \'布达佩斯大饭店\', \'阿凡达\', \'剪刀手爱德华\', \'摩登时代\', \'勇敢的心\', \'天使爱美丽\', \'喜剧之王\', \'致命ID\', \'加勒比海盗\', \'断背山\', \'杀人回忆\', \'狩猎\', \'哈利·波特与死亡圣器(下)\', \'幽灵公主\']
[\'请以你的名字呼唤我\', \'阳光灿烂的日子\', \'入殓师\', \'重庆森林\', \'小森林 夏秋篇\', \'第六感\', \'7号房的礼物\', \'消失的爱人\', \'红辣椒\', \'小森林 冬春篇\', \'爱在黎明破晓前\', \'侧耳倾听\', \'玛丽和马克思\', \'一一\', \'唐伯虎点秋香\', \'告白\', \'超脱\', \'蝙蝠侠:黑暗骑士崛起\', \'倩女幽魂\', \'大鱼\', \'阳光姐妹淘\', \'射雕英雄传之东成西就\', \'萤火之森\', \'甜蜜蜜\', \'驯龙高手\']
[\'无人知晓\', \'超能陆战队\', \'幸福终点站\', \'借东西的小人阿莉埃蒂\', \'菊次郎的夏天\', \'爱在日落黄昏时\', \'恐怖直播\', \'完美的世界\', \'神偷奶爸\', \'怪兽电力公司\', \'玩具总动员3\', \'血战钢锯岭\', \'功夫\', \'风之谷\', \'傲慢与偏见\', \'人生果实\', \'上帝之城\', \'时空恋旅人\', \'教父3\', \'电锯惊魂\', \'天书奇谭\', \'喜宴\', \'英雄本色\', \'谍影重重3\', \'被解救的姜戈\']
[\'岁月神偷\', \'七武士\', \'哪吒闹海\', \'我是山姆\', \'疯狂原始人\', \'头号玩家\', \'纵横四海\', \'三块广告牌\', \'釜山行\', \'心迷宫\', \'达拉斯买家俱乐部\', \'萤火虫之墓\', \'真爱至上\', \'荒蛮故事\', \'贫民窟的百万富翁\', \'东邪西毒\', \'记忆碎片\', \'爆裂鼓手\', \'你的名字。\', \'黑天鹅\', \'花样年华\', \'哈利·波特与阿兹卡班的囚徒\', \'卢旺达饭店\', \'忠犬八公物语\', \'黑客帝国3:矩阵革命\']
[\'模仿游戏\', \'头脑特工队\', \'一个叫欧维的男人决定去死\', \'哈利·波特与密室\', \'雨人\', \'你看起来好像很好吃\', \'未麻的部屋\', \'无敌破坏王\', \'恋恋笔记本\', \'冰川时代\', \'新世界\', \'海街日记\', \'二十二\', \'海边的曼彻斯特\', \'虎口脱险\', \'房间\', \'惊魂记\', \'恐怖游轮\', \'魔女宅急便\', \'奇迹男孩\', \'人工智能\', \'雨中曲\', \'疯狂的石头\', \'罗生门\', \'爱在午夜降临前\']
[\'小偷家族\', \'海洋\', \'终结者2:审判日\', \'初恋这件小事\', \'魂断蓝桥\', \'燃情岁月\', \'可可西里\', \'绿里奇迹\', \'穿越时空的少女\', \'2001太空漫游\', \'牯岭街少年杀人事件\', \'城市之光\', \'完美陌生人\', \'无耻混蛋\', \'阿飞正传\', \'新龙门客栈\', \'源代码\', \'香水\', \'谍影重重2\', \'青蛇\', \'地球上的星星\', \'谍影重重\', \'色,戒\', \'战争之王\', \'血钻\']
[\'遗愿清单\', \'猜火车\', \'大佛普拉斯\', \'疯狂的麦克斯4:狂暴之路\', \'步履不停\', \'彗星来的那一夜\', \'朗读者\', \'浪潮\', \'小萝莉的猴神大叔\', \'再次出发之纽约遇见你\', \'驴得水\', \'聚焦\', \'东京物语\', \'追随\', \'九品芝麻官\', \'一次别离\', \'哈利·波特与火焰杯\', \'千钧一发\', \'我爱你\', \'黑鹰坠落\', \'四个春天\', \'网络谜踪\', \'发条橙\', \'E.T. 外星人\', \'波西米亚狂想曲\']
Time consuming:1.792207956314087

aiohttp抓取:

import asyncio
from aiohttp import ClientSession
import time
from lxml import etree


async def load(url, semaphore):
    \'\'\'
    请求函数
    :param url: 请求页面路由
    :param semaphore: 限制最大并发对象
    :return:返回页面信息
    \'\'\'
    headers = {
        \'user-agent\': \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36\',
        }
    async with semaphore:
        async with ClientSession() as session:
            async with session.get(url, headers=headers) as response:
                return await response.text()
                pass
            pass
        pass
    pass


async def pars(url, semaphore):
    \'\'\'
    解析函数
    :param url: 请求页面路由
    :param semaphore:  限制最大并发对象
    :return:
    \'\'\'
    text = await load(url, semaphore)  # 获取异步请求返回的值
    html = etree.HTML(text)
    title_list = html.xpath(\'//div[@class="item"]/div/a/img/@alt\')
    print(title_list)
    pass

tasks = []
semaphore = asyncio.Semaphore(500)  # 限制并发次数,设置并发数为500,处理速度更快
loop = asyncio.get_event_loop()  # 创建事件循环对象
start = time.time()
for page in range(0, 250, 25):
    url = f"https://movie.douban.com/top250?start={page}"
    task = asyncio.ensure_future(pars(url, semaphore))  # 加入到任务列表
    tasks.append(task)
    pass
loop.run_until_complete(asyncio.wait(tasks))  # 执行异步任务
end = time.time()

print(f"Time consuming:{end -start}")

执行结果:最终耗时0.39,速度提升了四倍多

[\'蝙蝠侠:黑暗骑士\', \'控方证人\', \'活着\', \'乱世佳人\', \'寻梦环游记\', \'末代皇帝\', \'摔跤吧!爸爸\', \'指环王3:王者无敌\', \'何以为家\', \'少年派的奇幻漂流\', \'飞屋环游记\', \'十二怒汉\', \'鬼子来了\', \'天空之城\', \'哈尔的移动城堡\', \'大话西游之月光宝盒\', \'素媛\', \'天堂电影院\', \'罗马假日\', \'闻香识女人\', \'辩护人\', \'哈利·波特与魔法石\', \'搏击俱乐部\', \'我不是药神\', \'死亡诗社\']
[\'肖申克的救赎\', \'霸王别姬\', \'阿甘正传\', \'这个杀手不太冷\', \'美丽人生\', \'泰坦尼克号\', \'千与千寻\', \'辛德勒的名单\', \'盗梦空间\', \'忠犬八公的故事\', \'海上钢琴师\', \'楚门的世界\', \'三傻大闹宝莱坞\', \'机器人总动员\', \'放牛班的春天\', \'星际穿越\', \'大话西游之大圣娶亲\', \'熔炉\', \'疯狂动物城\', \'无间道\', \'龙猫\', \'教父\', \'当幸福来敲门\', \'怦然心动\', \'触不可及\']
[\'遗愿清单\', \'猜火车\', \'大佛普拉斯\', \'疯狂的麦克斯4:狂暴之路\', \'步履不停\', \'彗星来的那一夜\', \'朗读者\', \'浪潮\', \'小萝莉的猴神大叔\', \'再次出发之纽约遇见你\', \'驴得水\', \'聚焦\', \'东京物语\', \'追随\', \'九品芝麻官\', \'一次别离\', \'哈利·波特与火焰杯\', \'千钧一发\', \'我爱你\', \'黑鹰坠落\', \'四个春天\', \'网络谜踪\', \'发条橙\', \'E.T. 外星人\', \'波西米亚狂想曲\']
[\'小偷家族\', \'海洋\', \'终结者2:审判日\', \'初恋这件小事\', \'魂断蓝桥\', \'燃情岁月\', \'可可西里\', \'绿里奇迹\', \'穿越时空的少女\', \'2001太空漫游\', \'牯岭街少年杀人事件\', \'城市之光\', \'完美陌生人\', \'无耻混蛋\', \'阿飞正传\', \'新龙门客栈\', \'源代码\', \'香水\', \'谍影重重2\', \'青蛇\', \'地球上的星星\', \'谍影重重\', \'色,戒\', \'战争之王\', \'血钻\']
[\'美国往事\', \'海蒂和爷爷\', \'致命魔术\', \'低俗小说\', \'七宗罪\', \'沉默的羔羊\', \'蝴蝶效应\', \'春光乍泄\', \'禁闭岛\', \'心灵捕手\', \'被嫌弃的松子的一生\', \'布达佩斯大饭店\', \'阿凡达\', \'剪刀手爱德华\', \'摩登时代\', \'勇敢的心\', \'天使爱美丽\', \'喜剧之王\', \'致命ID\', \'加勒比海盗\', \'断背山\', \'杀人回忆\', \'狩猎\', \'哈利·波特与死亡圣器(下)\', \'幽灵公主\']
[\'岁月神偷\', \'七武士\', \'哪吒闹海\', \'我是山姆\', \'疯狂原始人\', \'头号玩家\', \'纵横四海\', \'三块广告牌\', \'釜山行\', \'心迷宫\', \'达拉斯买家俱乐部\', \'萤火虫之墓\', \'真爱至上\', \'荒蛮故事\', \'贫民窟的百万富翁\', \'东邪西毒\', \'记忆碎片\', \'爆裂鼓手\', \'你的名字。\', \'黑天鹅\', \'花样年华\', \'哈利·波特与阿兹卡班的囚徒\', \'卢旺达饭店\', \'忠犬八公物语\', \'黑客帝国3:矩阵革命\']
[\'教父2\', \'指环王2:双塔奇兵\', \'狮子王\', \'窃听风暴\', \'大闹天宫\', \'指环王1:魔戒再现\', \'两杆大烟枪\', \'美丽心灵\', \'猫鼠游戏\', \'饮食男女\', \'飞越疯人院\', \'黑客帝国\', \'钢琴家\', \'V字仇杀队\', \'本杰明·巴顿奇事\', \'看不见的客人\', \'让子弹飞\', \'西西里的美丽传说\', \'小鞋子\', \'拯救大兵瑞恩\', \'海豚湾\', \'情书\', \'穿条纹睡衣的男孩\', \'音乐之声\', \'绿皮书\']
[\'模仿游戏\', \'头脑特工队\', \'一个叫欧维的男人决定去死\', \'哈利·波特与密室\', \'雨人\', \'你看起来好像很好吃\', \'未麻的部屋\', \'无敌破坏王\', \'恋恋笔记本\', \'冰川时代\', \'新世界\', \'海街日记\', \'二十二\', \'海边的曼彻斯特\', \'虎口脱险\', \'房间\', \'惊魂记\', \'恐怖游轮\', \'魔女宅急便\', \'奇迹男孩\', \'人工智能\', \'雨中曲\', \'疯狂的石头\', \'罗生门\', \'爱在午夜降临前\']
[\'无人知晓\', \'超能陆战队\', \'幸福终点站\', \'借东西的小人阿莉埃蒂\', \'菊次郎的夏天\', \'爱在日落黄昏时\', \'恐怖直播\', \'完美的世界\', \'神偷奶爸\', \'怪兽电力公司\', \'玩具总动员3\', \'血战钢锯岭\', \'功夫\', \'风之谷\', \'傲慢与偏见\', \'人生果实\', \'上帝之城\', \'时空恋旅人\', \'教父3\', \'电锯惊魂\', \'天书奇谭\', \'喜宴\', \'英雄本色\', \'谍影重重3\', \'被解救的姜戈\']
[\'请以你的名字呼唤我\', \'阳光灿烂的日子\', \'入殓师\', \'重庆森林\', \'小森林 夏秋篇\', \'第六感\', \'7号房的礼物\', \'消失的爱人\', \'红辣椒\', \'小森林 冬春篇\', \'爱在黎明破晓前\', \'侧耳倾听\', \'玛丽和马克思\', \'一一\', \'唐伯虎点秋香\', \'告白\', \'超脱\', \'蝙蝠侠:黑暗骑士崛起\', \'倩女幽魂\', \'大鱼\', \'阳光姐妹淘\', \'射雕英雄传之东成西就\', \'萤火之森\', \'甜蜜蜜\', \'驯龙高手\']
Time consuming:0.39294934272766113

假如你的并发达到2000个,程序会报错:ValueError: too many file descriptors in select()。报错的原因字面上看是 Python 调取的 select 对打开的文件有最大数量的限制,这个其实是操作系统的限制,linux打开文件的最大数默认是1024,windows默认是509,超过了这个值,程序就开始报错。这里我们有三种方法解决这个问题:

1.限制并发数量。(一次不要塞那么多任务,或者限制最大并发数量)

2.使用回调的方式。

3.修改操作系统打开文件数的最大限制,在系统里有个配置文件可以修改默认值,具体步骤不再说明了。

不修改系统默认配置的话,个人推荐限制并发数的方法,设置并发数为500,处理速度更快。

分类:

技术点:

相关文章:

  • 2021-04-14
  • 2021-10-12
  • 2021-12-03
  • 2021-11-04
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-12-04
  • 2021-10-24
  • 2022-03-01
  • 2022-12-23
  • 2021-11-04
  • 2021-07-12
相关资源
相似解决方案