python如何提升爬虫效率


Posted in Python onSeptember 27, 2020

单线程+多任务异步协程

  • 协程

在函数(特殊函数)定义的时候,使用async修饰,函数调用后,内部语句不会立即执行,而是会返回一个协程对象

  • 任务对象

任务对象=高级的协程对象(进一步封装)=特殊的函数
任务对象必须要注册到时间循环对象中
给任务对象绑定回调:爬虫的数据解析中

  • 事件循环

当做是一个装载任务对象的容器
当启动事件循环对象的时候,存储在内的任务对象会异步执行

  • 特殊函数内部不能写不支持异步请求的模块,如time,requests...否则虽然不报错但实现不了异步

time.sleep -- asyncio.sleep
requests -- aiohttp

import asyncio
import time

start_time = time.time()
async def get_request(url):
  await asyncio.sleep(2)
  print(url,'下载完成!')

urls = [
  'www.1.com',
  'www.2.com',
]

task_lst = [] # 任务对象列表
for url in urls:
  c = get_request(url) # 协程对象
  task = asyncio.ensure_future(c) # 任务对象
  # task.add_done_callback(...)  # 绑定回调
  task_lst.append(task)

loop = asyncio.get_event_loop() # 事件循环对象
loop.run_until_complete(asyncio.wait(task_lst)) # 注册,手动挂起

线程池+requests模块

# 线程池
import time
from multiprocessing.dummy import Pool

start_time = time.time()
url_list = [
  'www.1.com',
  'www.2.com',
  'www.3.com',
]
def get_request(url):
  print('正在下载...',url)
  time.sleep(2)
  print('下载完成!',url)

pool = Pool(3)
pool.map(get_request,url_list)
print('总耗时:',time.time()-start_time)

两个方法提升爬虫效率

起一个flask服务端

from flask import Flask
import time

app = Flask(__name__)

@app.route('/bobo')
def index_bobo():
  time.sleep(2)
  return 'hello bobo!'

@app.route('/jay')
def index_jay():
  time.sleep(2)
  return 'hello jay!'

@app.route('/tom')
def index_tom():
  time.sleep(2)
  return 'hello tom!'

if __name__ == '__main__':
  app.run(threaded=True)

aiohttp模块+单线程多任务异步协程

import asyncio
import aiohttp
import requests
import time

start = time.time()
async def get_page(url):
  # page_text = requests.get(url=url).text
  # print(page_text)
  # return page_text
  async with aiohttp.ClientSession() as s: #生成一个session对象
    async with await s.get(url=url) as response:
      page_text = await response.text()
      print(page_text)
  return page_text

urls = [
  'http://127.0.0.1:5000/bobo',
  'http://127.0.0.1:5000/jay',
  'http://127.0.0.1:5000/tom',
]
tasks = []
for url in urls:
  c = get_page(url)
  task = asyncio.ensure_future(c)
  tasks.append(task)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

end = time.time()
print(end-start)

# 异步执行!
# hello tom!
# hello bobo!
# hello jay!
# 2.0311079025268555
'''
aiohttp模块实现单线程+多任务异步协程
并用xpath解析数据
'''
import aiohttp
import asyncio
from lxml import etree
import time

start = time.time()
# 特殊函数:请求的发送和数据的捕获
# 注意async with await关键字
async def get_request(url):
  async with aiohttp.ClientSession() as s:
    async with await s.get(url=url) as response:
      page_text = await response.text()
      return page_text    # 返回页面源码

# 回调函数,解析数据
def parse(task):
  page_text = task.result()
  tree = etree.HTML(page_text)
  msg = tree.xpath('/html/body/ul//text()')
  print(msg)

urls = [
  'http://127.0.0.1:5000/bobo',
  'http://127.0.0.1:5000/jay',
  'http://127.0.0.1:5000/tom',
]
tasks = []
for url in urls:
  c = get_request(url)
  task = asyncio.ensure_future(c)
  task.add_done_callback(parse) #绑定回调函数!
  tasks.append(task)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

end = time.time()
print(end-start)

requests模块+线程池

import time
import requests
from multiprocessing.dummy import Pool

start = time.time()
urls = [
  'http://127.0.0.1:5000/bobo',
  'http://127.0.0.1:5000/jay',
  'http://127.0.0.1:5000/tom',
]
def get_request(url):
  page_text = requests.get(url=url).text
  print(page_text)
  return page_text

pool = Pool(3)
pool.map(get_request, urls)
end = time.time()
print('总耗时:', end-start)

# 实现异步请求
# hello jay!
# hello bobo!
# hello tom!
# 总耗时: 2.0467123985290527

小结

  • 爬虫的加速目前掌握了两种方法:

aiohttp模块+单线程多任务异步协程
requests模块+线程池

  • 爬虫接触的模块有三个:

requests
urllib
aiohttp

  • 接触了一下flask开启服务器

以上就是python如何提升爬虫效率的详细内容,更多关于python提升爬虫效率的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python xlrd读取excel日期类型的2种方法
Apr 28 Python
深入解析Python中的WSGI接口
May 11 Python
python实现数值积分的Simpson方法实例分析
Jun 05 Python
Python学习小技巧之列表项的推导式与过滤操作
May 20 Python
解决pandas 作图无法显示中文的问题
May 24 Python
python字符串常用方法
Jun 14 Python
Python迭代器与生成器用法实例分析
Jul 09 Python
Centos下实现安装Python3.6和Python2共存
Aug 15 Python
python实现Flappy Bird源码
Dec 24 Python
Python SSL证书验证问题解决方案
Jan 13 Python
python中upper是做什么用的
Jul 20 Python
Python如何给函数库增加日志功能
Aug 04 Python
python操作链表的示例代码
Sep 27 #Python
python用tkinter实现一个简易能进行随机点名的界面
Sep 27 #Python
python实现暗通道去雾算法的示例
Sep 27 #Python
谈谈python垃圾回收机制
Sep 27 #Python
如何在python中处理配置文件代码实例
Sep 27 #Python
Python 开发工具通过 agent 代理使用的方法
Sep 27 #Python
python 读取、写入txt文件的示例
Sep 27 #Python
You might like
main.php
2006/12/09 PHP
PHP memcache扩展的三种安装方法
2009/04/26 PHP
两级联动select刷新后其值保持不变的实现方法
2014/01/27 PHP
解决PHP Opcache 缓存刷新、代码重载出现无法更新代码的问题
2020/08/24 PHP
浅谈PHP中的那些魔术常量
2020/12/02 PHP
表单(FORM)的一些实用效果代码
2007/03/25 Javascript
js parseInt("08")未指定进位制问题
2010/06/19 Javascript
jQuery客户端分页实例代码
2013/11/18 Javascript
jQuery中的read和JavaScript中的onload函数的区别
2014/08/27 Javascript
用svg制作富有动态的tooltip
2015/07/17 Javascript
bootstrap输入框组使用方法
2017/02/07 Javascript
JavaScript原生数组Array常用方法
2017/04/06 Javascript
bootstrap datetimepicker控件位置异常的解决方法
2017/11/23 Javascript
JS实现的将html转为pdf功能【基于浏览器端插件jsPDF】
2018/02/06 Javascript
JavaScript表格隔行变色和Tab标签页特效示例【附jQuery版】
2019/07/11 jQuery
微信小程序 拍照或从相册选取图片上传代码实例
2019/08/28 Javascript
JavaScript的垃圾回收机制与内存管理
2020/08/06 Javascript
Node.js文本文件BOM头的去除方法
2020/11/22 Javascript
Python导入txt数据到mysql的方法
2015/04/08 Python
Python实现翻转数组功能示例
2018/01/12 Python
Python格式化日期时间操作示例
2018/06/28 Python
Python+OpenCV图片局部区域像素值处理详解
2019/01/23 Python
keras-siamese用自己的数据集实现详解
2020/06/10 Python
完美解决torch.cuda.is_available()一直返回False的玄学方法
2021/02/06 Python
css3的transition属性详解
2014/12/15 HTML / CSS
HTML5里autofocus自动聚焦属性使用介绍
2016/06/22 HTML / CSS
巴西葡萄酒商店:Divvino
2020/02/22 全球购物
上海奥佳笔试题面试题
2016/11/16 面试题
计算机专业个人求职信范例
2013/09/23 职场文书
医学院校毕业生自荐信范文
2014/01/01 职场文书
小学清明节活动方案
2014/03/08 职场文书
销售团队获奖感言
2014/08/14 职场文书
2014年社区民政工作总结
2014/12/02 职场文书
幼师辞职信范文
2015/02/27 职场文书
Python的三个重要函数详解
2022/01/18 Python
Vue自定义铃声提示音组件的实现
2022/01/22 Vue.js