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爬虫之抓取糗事百科代码分享
Nov 06 Python
分析Python编程时利用wxPython来支持多线程的方法
Apr 07 Python
python 连接各类主流数据库的实例代码
Jan 30 Python
python爬虫爬取淘宝商品信息(selenum+phontomjs)
Feb 24 Python
用Python将结果保存为xlsx的方法
Jan 28 Python
Django ImageFiled上传照片并显示的方法
Jul 28 Python
Python 通过截图匹配原图中的位置(opencv)实例
Aug 27 Python
浅谈图像处理中掩膜(mask)的意义
Feb 19 Python
python 在threading中如何处理主进程和子线程的关系
Apr 25 Python
tensorflow图像裁剪进行数据增强操作
Jun 30 Python
Java Unsafe类实现原理及测试代码
Sep 15 Python
python如何实现word批量转HTML
Sep 30 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进行MySQL删除记录操作代码
2008/06/07 PHP
php 无限级缓存的类的扩展
2009/03/16 PHP
PHP JS Ip地址及域名格式检测代码
2013/09/27 PHP
PHP根据IP判断地区名信息的示例代码
2014/03/03 PHP
微信支付开发订单查询实例
2016/07/12 PHP
php性能分析之php-fpm慢执行日志slow log用法浅析
2016/10/17 PHP
浅谈Yii乐观锁的使用及原理
2017/07/25 PHP
关于javascript 回调函数中变量作用域的讨论
2009/09/11 Javascript
原生js写的放大镜效果
2012/08/22 Javascript
Extjs显示从数据库取出时间转换JSON后的出现问题
2012/11/20 Javascript
利用js正则表达式验证手机号,email地址,邮政编码
2014/01/23 Javascript
AngularJS 工作原理详解
2016/08/18 Javascript
详解Node.js串行化流程控制
2017/05/04 Javascript
jQuery 中msgTips 顶部弹窗效果实现代码
2017/08/14 jQuery
微信小程序保存多张图片的实现方法
2019/03/05 Javascript
VUE 直接通过JS 修改html对象的值导致没有更新到数据中解决方法分析
2019/12/02 Javascript
Vue如何使用混合Mixins和插件开发详解
2020/02/05 Javascript
js编写简易的计算器
2020/07/29 Javascript
springboot+vue实现文件上传下载
2020/11/17 Vue.js
python实现红包裂变算法
2016/02/16 Python
Python3.6正式版新特性预览
2016/12/15 Python
python_opencv用线段画封闭矩形的实例
2018/12/05 Python
Django框架 信号调度原理解析
2019/09/04 Python
python爬虫学习笔记之pyquery模块基本用法详解
2020/04/09 Python
python集合能干吗
2020/07/19 Python
利用CSS3的特性改变文本选中时的颜色
2013/09/11 HTML / CSS
常用的四种CSS透明属性介绍
2014/04/12 HTML / CSS
详解如何在css中引入自定义字体(font-face)
2018/05/17 HTML / CSS
Fox Racing官方网站:越野摩托车和山地自行车装备和服装
2019/12/23 全球购物
英国森林假期:Forest Holidays
2021/01/01 全球购物
2013年高中生自我评价
2013/10/23 职场文书
2014全国两会心得体会
2014/03/17 职场文书
煤矿安全协议书
2014/08/20 职场文书
2015初中生物教研组工作总结
2015/07/21 职场文书
600字作文之感受大自然
2019/11/27 职场文书
Spring Boot配合PageHelper优化大表查询数据分页
2022/04/20 Java/Android