一个不简单的异步爬虫小程序
说到Python,爬虫可能是大家第一个想到的。
然而,Python在爬虫方面已经产生了巨大的变化。虽然本次的小程序并不简单,不过你们可以尝试着了解一下,在Python3中如何书写一个爬虫。
相关库
本次,我们使用的库并不是`requests`库,而是仅仅支持`Python3.4.2+`的`aiohttp`。
首先我们需要搭建相关的环境:
安装`aiohttp`
pip install aiohttp
安装`cchardet`
pip3 install cchardet
安装`aiodns`
pip3 install aiodns
以上库基本上都没有依赖问题,可以直接安装。
## 目标
例如:`URL — http://flupy.org/data/flags/cn/cn.gif`的内容是一面中国国旗(希望大家做一个爱国的好公民)
![img](http://flupy.org/data/flags/cn/cn.gif)
当然,国旗不只这一面,我们我们只要吧`url`中的`cn/cn.gif`换成别的国家,就可以拿到别的国家的旗子。
例如:`URL — http://flupy.org/data/flags/us/us.gif`的内容是一面美国国旗(us是美国的国家代码)
![img](http://flupy.org/data/flags/us/us.gif)
因此,我们今天的目标就是:
`CN IN US ID BR PK NG BD RU JP MX PH VN ET EG DE IR TR CD FR`
这20个旗子
构造URL代码
为了构造这些目标,我们必须要先获得URL,因此我们通过`base_url`和`contry_codes`的形式分别存储URL共同的部分与不同的部分。
程序设计
主流程:
主流程一半是出现再`__name__`测试中的入口函数,使用它的目的一半是提供一个统一的接口,并且提供一个清晰的逻辑,以方便我们添加一些额外的信息。
该主流程,只有两个功能
1. 用来调用本程序真正的代码
2. 用来对整个代码的执行计时
实际流程:
在实际的流程中,我们需要开启一个事件循环,来处理我们的任务。
因此我们需要得到一个事件循环`loop`。来执行我们非阻塞的`coroutine`。当然,时间循环一单用完,需要关闭。
在这个流程中,`wait`可以通过许多的`coroutine`来构造一个非阻塞的`coroutine`。而且最后这个`coroutine`是在所有`coroutine`完成时才完成。
其实这个流程也只完成了两件事:
* 构造了循环
* 构造需要被时间循环执行的`coroutine`,并提交给循环
处理单个爬取的coroutine
记住,`download_many`的依然是一个普通的函数,但是它的作用是操作时间循环去调度`coroutine`,因此我们需要开始写我们的`coroutine`。
由上一部分可知,对应没一个旗子的`download_one`就是一个`coroutine`
此处分块处理的原因是因为,不确定图片的大小,可以保证不要一次性占用太多的内存空间。
从上面看出,所有的`coroutine`都是异步的,如果读者自己尝试一下。就会发现,与普通的排队式爬虫相比,速度提高了近16倍,甚至更多。
与使用多线程爬虫的效果相当,但是占用更少的资源,可以腾出更多的内存空间。
待改进
其实在此处,埋了一个伏笔,本程序还有待改进,它现在唯一不完美的地方是,对`pool`的重复利用不好,最好把session放入download_many中。
关注+转发谢谢亲们
- 一个秘密:眼睛长前面的,吃眼睛长两边的
- 您还有个福利没领,这里这里
- 一个双十二5折,成功解锁成都这座幸福城市的密码...
- 外星生物在哪里?NASA宣布发现另一个“太阳系”
- 【生活警惕】洗筷子时的一个动作,竟惹来“1级致癌物”
- 一个人没出息的9大表现,现在知道还不算晚
- 期待独一无二的你
- 墓园迎来冬至前最后一个周末 疏导到位交通平稳有序
- 身材很棒的小伙,努力自己开一个健身室,网友:身材好人又帅!
- 清洁血管,消除沉积的脂肪,一个简单的方法就可以!