一个简单的异步爬虫.
私信太多,统一回答一下:
关于异步函数的:
1. 真正派发任务的是 consumer 这个coroutine,所以也在内部做了并发控制.
2. process_content 用于获取html及保存到mysql.
关于异步相关(asyncio)的 :
1.await 相当于 yield from .
2.await 后面是一个coroutine, 普通函数不是coroutine,普通函数也不是通过加一个 async / asyncio.coroutine,就能真正
成为coroutine的,就算没报错,如果内部加了阻塞函数(time.sleep / read /write ) 还是一个阻塞函数;因此,往往我们自己的
coroutine只是一个中间层的东西,所以需要aiohttp , aiomysql等这个模块来提供支持,就跟tornado的异步框架一样,如果你
在get()/post() 中加了阻塞函数调用,tornado 还是阻塞的.
3. 这个问题问的有点多 .
1. await 后面可以是 Task,Future,async def xxx() ( 自定义函数) ,因此在加入loop 时,将自动封装我们自定义的coroutine成为一个 Task / Future 对象.
* 2. 无论是 await 还是 asyncio.ensure_future/async , 都将把coroutine加入loop中,但是两者有一个差别:
await 是等待这个coroutine 运行完成, ensure_future/async 不会等待直接仍入循环体中运行.
这个就是下面代码中一会用await 一会用ensure_future/async .同样的也是很多人问,
为什么在控制 coroutine 的时候: async with sem 后面用ensure_future 控制不了的原因
3.额外说明一下Future对象. 下面代码中没有自行创建Future对象, 其实也可以用, Future对象与Twisted中的
Defer对象极其类似. 只不过Future 对象一般都是 await Future, 当然也可以使用回调: Future.add_done_callback.
而Defer对象是使用2个回调链的方式.具体可参考我写的:Twisted
这2个对象都在Future.set_result