作者:小K
来源:麦叔编程
❝
上次的Python三分钟带大家写了一把协程函数,然后给大家留了2个跟协程有关的话题让大家选。
看了下评论区,选择协程爬虫的同学比较多。
❞
那么今天就安排协程爬虫的内容。
aiohttp模块上期的文章我强调了,协程函数中不能使用同步的函数或模块。
我们在一般的爬虫程序中基本上都会用requests模块,对目标网站发起请求并获得响应。
import requests r = requests.get("http://www.baidu.com") print(r.text)
但是在async函数中如果出现requests模块,那么这个async函数就会变成普通函数。
所以如果想要在async函数中发起异步请求,那么就一定需要对应的模块对它进行支持。
在这我介绍一个模块 -- aiohttp,它是能够写入async函数中并对web端发起请求。
结合代码看一下,
import asyncio from aiohttp import ClientSession url = "http://www.baidu.com" async def spider(url): async with ClientSession() as session: async with session.get(url) as response: response = await response.read() print(response) if __name__ == '__main__': loop = asyncio.get_event_loop() loop.run_until_complete(spider(url))
代码说明:
模块
import asyncio from aiohttp import ClientSession
导入要用的协程模块,
from aiohttp import ClientSession
类似于用requests模块创建了一个session,创建了一个与web之间的会话。
主函数部分直接看代码注释吧~
async def spider(url): # 使用ClientSession创建了一个session会话。 async with ClientSession() as session: # 使用session去请求目标站,并取回响应报文。 async with session.get(url) as response: # 获得响应报文 response = await response.read() print(response)
❝
肯定有小伙伴好奇,为什么函数中会出现async和await这样的字眼?
❞
我先解释下await的作用是什么,爬虫在发起请求之后,需要服务端对我们的这个请求(request)进行处理分析,有些比较繁忙的服务器还要等待一些时间才会给我返回响应。
所以为了避免时间浪费,await表示这一步操作可以挂起不等待。
❝
就像一人操作多台洗衣机那样,启动洗衣机后,根本没有没有必要守着,可以去处理别的事情。
等衣服洗完之后,我再来取出衣服。
❞
而async代表的就是,我这个事件在你await之后是可以来处理的。
上面的代码,我只注册一个task放入loop循环事件中。
下面我们将尝试放入N个task,开启高速爬虫之旅。
「为了避免崩了他人服务器,本次测试的url将使用Baidu作例子。」
import time import asyncio from aiohttp import ClientSession tasks = [] url = "http://www.baidu.com" async def spider(url): async with ClientSession() as session: async with session.get(url) as response: response = await response.read() # print(response) print(f"get reponse time: {time.time()}") def run(): for i in range(1000): task = asyncio.ensure_future(spider(url)) tasks.append(task) if __name__ == '__main__': loop = asyncio.get_event_loop() run() loop.run_until_complete(asyncio.wait(tasks))
上面的代码中,将1000个向Baidu发起请求的task注册进了loop循环中,
执行代码之后本机将会向Baidu发起1000次请求。
❝
对于代码来说可能我们可能改几个0就会对方服务器造成很大的压力,所以大家练练手就行。
「崩了对方服务器是要进去的。」
❞
如果你也有一些疑问,请在评论区留言,
,