Python中利用aiohttp制作异步爬虫及简单应用


Posted in Python onNovember 29, 2018

摘要: 简介 asyncio可以实现单线程并发IO操作,是Python中常用的异步处理模块。关于asyncio模块的介绍,笔者会在后续的文章中加以介绍,本文将会讲述一个基于asyncio实现的HTTP框架——aiohttp,它可以帮助我们异步地实现HTTP请求,从而使得我们的程序效率大大提高。

简介

asyncio可以实现单线程并发IO操作,是Python中常用的异步处理模块。关于asyncio模块的介绍,笔者会在后续的文章中加以介绍,本文将会讲述一个基于asyncio实现的HTTP框架——aiohttp,它可以帮助我们异步地实现HTTP请求,从而使得我们的程序效率大大提高。

本文将会介绍aiohttp在爬虫中的一个简单应用。

在原来的项目中,我们是利用Python的爬虫框架scrapy来爬取当当网图书畅销榜的图书信息的。在本文中,笔者将会以两种方式来制作爬虫,比较同步爬虫与异步爬虫(利用aiohttp实现)的效率,展示aiohttp在爬虫方面的优势。

同步爬虫

首先,我们先来看看用一般的方法实现的爬虫,即同步方法,完整的Python代码如下:

'''
同步方式爬取当当畅销书的图书信息
'''
import time
import requests
import pandas as pd
from bs4 import BeautifulSoup
# table表格用于储存书本信息
table = []
# 处理网页
def download(url):
html = requests.get(url).text
# 利用BeautifulSoup将获取到的文本解析成HTML
soup = BeautifulSoup(html, "lxml")
# 获取网页中的畅销书信息
book_list = soup.find('ul', class_="bang_list clearfix bang_list_mode")('li')
for book in book_list:
info = book.find_all('div')
# 获取每本畅销书的排名,名称,评论数,作者,出版社
rank = info[0].text[0:-1]
name = info[2].text
comments = info[3].text.split('条')[0]
author = info[4].text
date_and_publisher = info[5].text.split()
publisher = date_and_publisher[1] if len(date_and_publisher) >= 2 else ''
# 将每本畅销书的上述信息加入到table中
table.append([rank, name, comments, author, publisher])
# 全部网页
urls = ['http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent7-0-0-1-%d' % i for i in range(1, 26)]
# 统计该爬虫的消耗时间
print('#' * 50)
t1 = time.time() # 开始时间
for url in urls:
download(url)
# 将table转化为pandas中的DataFrame并保存为CSV格式的文件
df = pd.DataFrame(table, columns=['rank', 'name', 'comments', 'author', 'publisher'])
df.to_csv('E://douban/dangdang.csv', index=False)
t2 = time.time() # 结束时间
print('使用一般方法,总共耗时:%s' % (t2 - t1))
print('#' * 50)

输出结果如下:

##################################################
使用一般方法,总共耗时:23.522345542907715
##################################################

程序运行了23.5秒,爬取了500本书的信息,效率还是可以的。我们前往目录中查看文件,如下:

Python中利用aiohttp制作异步爬虫及简单应用

异步爬虫

接下来我们看看用aiohttp制作的异步爬虫的效率,完整的源代码如下:

'''
异步方式爬取当当畅销书的图书信息
'''
import time
import aiohttp
import asyncio
import pandas as pd
from bs4 import BeautifulSoup
# table表格用于储存书本信息
table = []
# 获取网页(文本信息)
async def fetch(session, url):
async with session.get(url) as response:
return await response.text(encoding='gb18030')
# 解析网页
async def parser(html):
# 利用BeautifulSoup将获取到的文本解析成HTML
soup = BeautifulSoup(html, "lxml")
# 获取网页中的畅销书信息
book_list = soup.find('ul', class_="bang_list clearfix bang_list_mode")('li')
for book in book_list:
info = book.find_all('div')
# 获取每本畅销书的排名,名称,评论数,作者,出版社
rank = info[0].text[0:-1]
name = info[2].text
comments = info[3].text.split('条')[0]
author = info[4].text
date_and_publisher = info[5].text.split()
publisher = date_and_publisher[1] if len(date_and_publisher) >=2 else ''
# 将每本畅销书的上述信息加入到table中
table.append([rank,name,comments,author,publisher])
# 处理网页
async def download(url):
async with aiohttp.ClientSession() as session:
html = await fetch(session, url)
await parser(html)
# 全部网页
urls = ['http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent7-0-0-1-%d'%i for i in range(1,26)]
# 统计该爬虫的消耗时间
print('#' * 50)
t1 = time.time() # 开始时间
# 利用asyncio模块进行异步IO处理
loop = asyncio.get_event_loop()
tasks = [asyncio.ensure_future(download(url)) for url in urls]
tasks = asyncio.gather(*tasks)
loop.run_until_complete(tasks)
# 将table转化为pandas中的DataFrame并保存为CSV格式的文件
df = pd.DataFrame(table, columns=['rank','name','comments','author','publisher'])
df.to_csv('E://douban/dangdang.csv',index=False)
t2 = time.time() # 结束时间
print('使用aiohttp,总共耗时:%s' % (t2 - t1))
print('#' * 50)

我们可以看到,这个爬虫与原先的一般方法的爬虫的思路和处理方法基本一致,只是在处理HTTP请求时使用了aiohttp模块以及在解析网页时函数变成了协程(coroutine),再利用aysncio进行并发处理,这样无疑能够提升爬虫的效率。它的运行结果如下:

##################################################
使用aiohttp,总共耗时:2.405137538909912
##################################################

2.4秒,如此神奇!!!再来看看文件的内容:

Python中利用aiohttp制作异步爬虫及简单应用

总结

综上可以看出,利用同步方法和异步方法制作的爬虫的效率相差很大,因此,我们在实际制作爬虫的过程中,也不妨可以考虑异步爬虫,多多利用异步模块,如aysncio, aiohttp。另外,aiohttp只支持3.5.3以后的Python版本。

Python 相关文章推荐
Python中pygame的mouse鼠标事件用法实例
Nov 11 Python
Python的网络编程库Gevent的安装及使用技巧
Jun 24 Python
浅谈flask源码之请求过程
Jul 26 Python
对python 生成拼接xml报文的示例详解
Dec 28 Python
python利用wx实现界面按钮和按钮监听和字体改变的方法
Jul 17 Python
python PyQt5/Pyside2 按钮右击菜单实例代码
Aug 17 Python
Python从入门到精通之环境搭建教程图解
Sep 26 Python
Python标准库itertools的使用方法
Jan 17 Python
基于Python下载网络图片方法汇总代码实例
Jun 24 Python
五种Python转义表示法
Nov 27 Python
Pycharm 设置默认解释器路径和编码格式的操作
Feb 05 Python
浅谈Python中对象是如何被调用的
Apr 06 Python
Python中logging.NullHandler 的使用教程
Nov 29 #Python
Mac下Anaconda的安装和使用教程
Nov 29 #Python
windows7 32、64位下python爬虫框架scrapy环境的搭建方法
Nov 29 #Python
解决pycharm py文件运行后停止按钮变成了灰色的问题
Nov 29 #Python
pycharm debug功能实现跳到循环末尾的方法
Nov 29 #Python
在PyCharm下打包*.py程序成.exe的方法
Nov 29 #Python
selenium设置proxy、headers的方法(phantomjs、Chrome、Firefox)
Nov 29 #Python
You might like
强烈推荐:php.ini中文版(1)
2006/10/09 PHP
解析php中session的实现原理以及大网站应用应注意的问题
2013/06/17 PHP
php使用PDO事务配合表格读取大量数据插入操作实现方法
2017/02/16 PHP
ThinkPHP5.0框架验证码功能实现方法【基于第三方扩展包】
2019/03/11 PHP
深入浅析JavaScript中prototype和proto的关系
2015/11/15 Javascript
深入探讨前端框架react
2015/12/09 Javascript
JavaScript动态创建div等元素实例讲解
2016/01/06 Javascript
javascript创建对象的3种方法
2016/11/02 Javascript
详解vue组件化开发-vuex状态管理库
2017/04/10 Javascript
如何在AngularJs中调用第三方插件库
2017/05/21 Javascript
jQuery简单绑定单个事件的方法示例
2017/06/10 jQuery
利用vscode编写vue的简单配置详解
2017/06/17 Javascript
chorme 浏览器记住密码后input黄色背景处理方法(两种)
2017/11/22 Javascript
详解刷新页面vuex数据不消失和不跳转页面的解决
2018/01/30 Javascript
jquery获取元素到屏幕四周可视距离的方法
2018/09/05 jQuery
Vue实现类似Spring官网图片滑动效果方法
2019/03/01 Javascript
使用vuex解决刷新页面state数据消失的问题记录
2019/05/08 Javascript
详解mpvue中使用vant时需要注意的onChange事件的坑
2019/05/16 Javascript
vue 解决异步数据更新问题
2019/10/29 Javascript
pycharm 使用心得(四)显示行号
2014/06/05 Python
在Python中使用lambda高效操作列表的教程
2015/04/24 Python
Django实现后台上传并显示图片功能
2020/05/29 Python
Python魔术方法专题
2020/06/19 Python
纯CSS3+DIV实现小三角形边框效果的示例代码
2020/08/03 HTML / CSS
中东最大的在线宠物店:Dubai Pet Food
2020/06/11 全球购物
用JAVA实现一种排序,JAVA类实现序列化的方法(二种)
2014/04/23 面试题
借名购房协议书范本
2014/10/06 职场文书
春节慰问信范文
2015/02/15 职场文书
综合办公室岗位职责
2015/04/11 职场文书
十二生肖观后感
2015/06/12 职场文书
服务行业标语口号
2015/12/26 职场文书
2016年九九重阳节活动总结
2016/04/01 职场文书
超市啤酒狂欢夜策划方案范文!
2019/07/03 职场文书
600字作文之感受大自然
2019/11/27 职场文书
elasticSearch-api的具体操作步骤讲解
2021/06/28 Java/Android
javascript条件式访问属性和箭头函数介绍
2021/11/17 Javascript