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下载Bing图片(代码)
Nov 07 Python
Python求两个list的差集、交集与并集的方法
Nov 01 Python
Python3搜索及替换文件中文本的方法
May 22 Python
用virtualenv建立多个Python独立虚拟开发环境
Jul 06 Python
django实现同一个ip十分钟内只能注册一次的实例
Nov 03 Python
分析python动态规划的递归、非递归实现
Mar 04 Python
解决Tensorflow使用pip安装后没有model目录的问题
Jun 13 Python
使用Pytorch来拟合函数方式
Jan 14 Python
详解vscode实现远程linux服务器上Python开发
Nov 10 Python
python脚本使用阿里云slb对恶意攻击进行封堵的实现
Feb 04 Python
Anaconda配置各版本Pytorch的实现
Aug 07 Python
python lambda 表达式形式分析
Apr 03 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脚本的10个技巧(6)
2006/10/09 PHP
php完全过滤HTML,JS,CSS等标签
2009/01/16 PHP
浅析Dos下运行php.exe,出现没有找到php_mbstring.dll 错误的解决方法
2013/06/29 PHP
浅析ThinkPHP中的pathinfo模式和URL重写
2014/01/06 PHP
ThinkPHP的cookie和session冲突造成Cookie不能使用的解决方法
2014/07/01 PHP
Thinkphp 框架扩展之标签库驱动原理与用法分析
2020/04/23 PHP
IE8 浏览器Cookie的处理
2009/01/31 Javascript
给Function做的OOP扩展
2009/05/07 Javascript
javascript 限制输入脚本大全
2009/11/03 Javascript
JQuery 写的个性导航菜单
2009/12/24 Javascript
javascript页面加载完执行事件代码
2014/02/11 Javascript
一个jquery实现的不错的多行文字图片滚动效果
2014/09/28 Javascript
深入浅析JavaScript字符串操作方法 slice、substr、substring及其IE兼容性
2015/12/16 Javascript
Ext JS动态加载JavaScript创建窗体的方法
2016/06/23 Javascript
ros::spin() 和 ros::spinOnce()函数的区别及详解
2016/10/01 Javascript
微信小程序 页面跳转传递值几种方法详解
2017/01/12 Javascript
Ajax和Comet技术总结
2017/02/19 Javascript
angularJs的ng-class切换class
2017/06/23 Javascript
JavaScript实现三级联动效果
2017/07/15 Javascript
Vue from-validate 表单验证的示例代码
2017/09/26 Javascript
VUE重点问题总结
2018/03/19 Javascript
vue-cli3.0 特性解读
2018/04/22 Javascript
Vue全局分页组件的实现代码
2018/08/10 Javascript
CentOS 6.5下安装Python 3.5.2(与Python2并存)
2017/06/05 Python
python自动化报告的输出用例详解
2018/05/30 Python
python通过实例讲解反射机制
2019/10/17 Python
Python eval函数介绍及用法
2020/11/09 Python
丝芙兰巴西官方商城:SEPHORA巴西
2016/10/31 全球购物
澳大利亚最大的护发和护肤品购物网站:RY
2019/12/26 全球购物
毕业生的自我评价分享
2013/12/18 职场文书
服务员岗位职责
2014/01/29 职场文书
学校文明单位申报材料
2014/05/06 职场文书
目标责任书格式
2014/07/28 职场文书
优秀团员事迹材料1500字
2014/08/31 职场文书
2015年中学图书馆工作总结
2015/07/22 职场文书
企业愿景口号
2015/12/25 职场文书