如何通过aiohttp实现Python异步爬虫项目实战?
- 内容介绍
- 文章标签
- 相关推荐
本文共计929个文字,预计阅读时间需要4分钟。
目录- 引言- aiohttp是什么- requests与aiohttp区别- 安装aiohttp- aiohttp使用介绍- 基本实例- URL参数设置- 请求类型- 响应的几个方法- 超时设置- 并发限制- aiohttp异步爬取实战- 总结- 引言- aiohttp是什么- requests与aiohttp区别- 安装aiohttp- aiohttp使用介绍- 基本实例- URL参数设置- 请求类型- 响应的几个方法- 超时设置- 并发限制- aiohttp异步爬取实战- 总结
目录
- 引言
- aiowww.www.www.www.www.www.www.www.baidu.com') as response:
await asyncio.sleep(2)
# print(f'当前时间:{datetime.now()}, {response.status}')
async def main():
global session
session = aiodushu.baidu.com/pc/detail?gid=4308080950
目录接口:dushu.baidu.com/api/pc/getCatalog?data={"book_id":"4308080950"}
详情接口:
dushu.baidu.com/api/pc/getChapterContent?data={"book_id":"4295122774","cid":"4295122774|116332"}
关键参数:
book_id:小说ID、cid:章节id采集要求:使用协程方式写入,数据存放进mongo
需求分析:点开需求页面,通过F12抓包可以发现两个接口。一个目录接口,一个详情接口。
首先第一步先请求目录接口拿到cid章节id,然后将cid传递给详情接口拿到小说数据,最后存入mongo即可。话不多说,直接上代码:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Author : 钢铁知识库 # 不合适就是不合适,真正合适的,你不会有半点犹豫。 import asyncio import json,re import logging import aiodushu.baidu.com/api/pc/getCatalog?data={"book_id":"'+b_id+'"}' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/104.0.0.0 Safari/537.36" } # 并发声明 semaphore = asyncio.Semaphore(5) async def download(title,b_id, cid): data = { "book_id": b_id, "cid": f'{b_id}|{cid}', } data = json.dumps(data) detail_url = 'dushu.baidu.com/api/pc/getChapterContent?data={}'.format(data) async with semaphore: async with aiohttp.ClientSession(headers=headers) as session: async with session.get(detail_url) as response: res = await response.json() content = { 'title': title, 'content': res['data']['novel']['content'] } # print(title) await save_data(content) async def save_data(data): if data: client = ConnDb().conn_motor_mongo() db = client.baidu_novel collection = db.novel logging.info('saving data %s', data) await collection.update_one( {'title': data.get('title')}, {'$set': data}, upsert=True ) async def main(): res = requests.get(url, headers=headers) tasks = [] for re in res.json()['data']['novel']['items']: # 拿到某小说目录cid title = re['title'] cid = re['cid'] tasks.append(download(title, b_id, cid)) # 将请求放到列表里,再通过gather执行并发 await asyncio.gather(*tasks) if __name__ == '__main__': asyncio.run(main())
至此,我们就使用aiohttp完成了对小说章节的爬取。
要实现异步处理,得先要有挂起操作,当一个任务需要等待 IO 结果的时候,可以挂起当前任务,转而去执行其他任务,这样才能充分利用好资源,要实现异步,需要了解 await 的用法,使用 await 可以将耗时等待的操作挂起,让出控制权。当协程执行的时候遇到 await,时间循环就会将本协程挂起,转而去执行别的协程,直到其他的协程挂起或执行完毕。
await 后面的对象必须是如下格式之一:
- A native coroutine object returned from a native coroutine function,一个原生 coroutine 对象。
- A generator-based coroutine object returned from a function decorated with types.coroutine,一个由 types.coroutine 修饰的生成器,这个生成器可以返回 coroutine 对象。
- An object with anawaitmethod returning an iterator,一个包含await方法的对象返回的一个迭代器。
总结
以上就是借助协程async和异步aiohttp两个主要模块完成异步爬虫的内容,
aiohttp 以异步方式爬取网站的耗时远小于 requests 同步方式,以上列举的例子希望对你有帮助。注意,线程和协程是两个概念,后面找机会我们再聊聊进程和线程、线程和协程的关系
更多关于python aiohttp异步爬虫的资料请关注自由互联其它相关文章!
本文共计929个文字,预计阅读时间需要4分钟。
目录- 引言- aiohttp是什么- requests与aiohttp区别- 安装aiohttp- aiohttp使用介绍- 基本实例- URL参数设置- 请求类型- 响应的几个方法- 超时设置- 并发限制- aiohttp异步爬取实战- 总结- 引言- aiohttp是什么- requests与aiohttp区别- 安装aiohttp- aiohttp使用介绍- 基本实例- URL参数设置- 请求类型- 响应的几个方法- 超时设置- 并发限制- aiohttp异步爬取实战- 总结
目录
- 引言
- aiowww.www.www.www.www.www.www.www.baidu.com') as response:
await asyncio.sleep(2)
# print(f'当前时间:{datetime.now()}, {response.status}')
async def main():
global session
session = aiodushu.baidu.com/pc/detail?gid=4308080950
目录接口:dushu.baidu.com/api/pc/getCatalog?data={"book_id":"4308080950"}
详情接口:
dushu.baidu.com/api/pc/getChapterContent?data={"book_id":"4295122774","cid":"4295122774|116332"}
关键参数:
book_id:小说ID、cid:章节id采集要求:使用协程方式写入,数据存放进mongo
需求分析:点开需求页面,通过F12抓包可以发现两个接口。一个目录接口,一个详情接口。
首先第一步先请求目录接口拿到cid章节id,然后将cid传递给详情接口拿到小说数据,最后存入mongo即可。话不多说,直接上代码:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Author : 钢铁知识库 # 不合适就是不合适,真正合适的,你不会有半点犹豫。 import asyncio import json,re import logging import aiodushu.baidu.com/api/pc/getCatalog?data={"book_id":"'+b_id+'"}' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/104.0.0.0 Safari/537.36" } # 并发声明 semaphore = asyncio.Semaphore(5) async def download(title,b_id, cid): data = { "book_id": b_id, "cid": f'{b_id}|{cid}', } data = json.dumps(data) detail_url = 'dushu.baidu.com/api/pc/getChapterContent?data={}'.format(data) async with semaphore: async with aiohttp.ClientSession(headers=headers) as session: async with session.get(detail_url) as response: res = await response.json() content = { 'title': title, 'content': res['data']['novel']['content'] } # print(title) await save_data(content) async def save_data(data): if data: client = ConnDb().conn_motor_mongo() db = client.baidu_novel collection = db.novel logging.info('saving data %s', data) await collection.update_one( {'title': data.get('title')}, {'$set': data}, upsert=True ) async def main(): res = requests.get(url, headers=headers) tasks = [] for re in res.json()['data']['novel']['items']: # 拿到某小说目录cid title = re['title'] cid = re['cid'] tasks.append(download(title, b_id, cid)) # 将请求放到列表里,再通过gather执行并发 await asyncio.gather(*tasks) if __name__ == '__main__': asyncio.run(main())
至此,我们就使用aiohttp完成了对小说章节的爬取。
要实现异步处理,得先要有挂起操作,当一个任务需要等待 IO 结果的时候,可以挂起当前任务,转而去执行其他任务,这样才能充分利用好资源,要实现异步,需要了解 await 的用法,使用 await 可以将耗时等待的操作挂起,让出控制权。当协程执行的时候遇到 await,时间循环就会将本协程挂起,转而去执行别的协程,直到其他的协程挂起或执行完毕。
await 后面的对象必须是如下格式之一:
- A native coroutine object returned from a native coroutine function,一个原生 coroutine 对象。
- A generator-based coroutine object returned from a function decorated with types.coroutine,一个由 types.coroutine 修饰的生成器,这个生成器可以返回 coroutine 对象。
- An object with anawaitmethod returning an iterator,一个包含await方法的对象返回的一个迭代器。
总结
以上就是借助协程async和异步aiohttp两个主要模块完成异步爬虫的内容,
aiohttp 以异步方式爬取网站的耗时远小于 requests 同步方式,以上列举的例子希望对你有帮助。注意,线程和协程是两个概念,后面找机会我们再聊聊进程和线程、线程和协程的关系
更多关于python aiohttp异步爬虫的资料请关注自由互联其它相关文章!

