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 相关文章推荐
Python3读取UTF-8文件及统计文件行数的方法
May 22 Python
python一键升级所有pip package的方法
Jan 16 Python
python GUI实现小球满屏乱跑效果
May 09 Python
给我一面国旗 python帮你实现
Sep 30 Python
在python shell中运行python文件的实现
Dec 21 Python
Python自动采集微信联系人的实现示例
Feb 28 Python
Python模拟伯努利试验和二项分布代码实例
May 27 Python
python实现mask矩阵示例(根据列表所给元素)
Jul 30 Python
matplotlib交互式数据光标实现(mplcursors)
Jan 13 Python
Python答题卡识别并给出分数的实现代码
Jun 22 Python
基于Pygame实现简单的贪吃蛇游戏
Dec 06 Python
python实现对doc、txt、xls等文档的读写操作
Apr 02 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常用技巧总结(附函数代码)
2012/02/04 PHP
PHP漏洞全解(详细介绍)
2012/11/13 PHP
Zend Framework教程之响应对象的封装Zend_Controller_Response实例详解
2016/03/07 PHP
无需数据库在线投票调查php代码
2016/07/20 PHP
详解thinkphp5+swoole实现异步邮件群发(SMTP方式)
2017/10/13 PHP
javascript支持firefox,ie7页面布局拖拽效果代码
2007/12/20 Javascript
Javascript 获取LI里的内容
2008/12/17 Javascript
jQuery 前的按键判断代码
2010/03/19 Javascript
jquery组件使用中遇到的问题整理及解决
2014/02/21 Javascript
关于javaScript注册click事件传递参数的不成功问题
2014/07/18 Javascript
js判断鼠标左、中、右键哪个被点击的方法
2015/01/27 Javascript
简述JavaScript中正则表达式的使用方法
2015/06/15 Javascript
angularjs客户端实现压缩图片文件并上传实例
2015/07/06 Javascript
JS实现支持Ajax验证的表单插件
2016/03/24 Javascript
浅谈javascript基础之客户端事件驱动
2016/06/10 Javascript
Javascript将字符串日期格式化为yyyy-mm-dd的方法
2016/10/27 Javascript
JavaScript中匿名函数的递归调用
2017/01/22 Javascript
canvas实现粒子时钟效果
2017/02/06 Javascript
Vue-Router实现页面正在加载特效方法示例
2017/02/12 Javascript
微信小程序之蓝牙的链接
2017/09/26 Javascript
ES6入门教程之let、const的使用方法
2019/04/13 Javascript
vue-cli3配置与跨域处理方法
2019/08/17 Javascript
解决vue.js提交数组时出现数组下标的问题
2019/11/05 Javascript
Vue+Java 通过websocket实现服务器与客户端双向通信操作
2020/09/22 Javascript
Python 功能和特点(新手必学)
2015/12/30 Python
linux中如何使用python3获取ip地址
2019/07/15 Python
django 微信网页授权登陆的实现
2019/07/30 Python
Python实现滑动平均(Moving Average)的例子
2019/08/24 Python
pytorch nn.Conv2d()中的padding以及输出大小方式
2020/01/10 Python
作为网站管理者应当如何防范XSS
2014/08/16 面试题
旅游管理本科生求职信
2013/10/14 职场文书
材料会计岗位职责
2014/03/06 职场文书
机电一体化毕业生自荐信
2014/06/19 职场文书
个人创业事迹材料
2014/12/30 职场文书
升职自我推荐信范文
2015/03/25 职场文书
《伯牙绝弦》教学反思
2016/02/16 职场文书