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装饰器 免去调用父类构造函数的麻烦
May 18 Python
Python读取图片EXIF信息类库介绍和使用实例
Jul 10 Python
用Python中的字典来处理索引统计的方法
May 05 Python
python计算圆周率pi的方法
Jul 11 Python
Pycharm代码无法复制,无法选中删除,无法编辑的解决方法
Oct 22 Python
pandas通过字典生成dataframe的方法步骤
Jul 23 Python
python3中的eval和exec的区别与联系
Oct 10 Python
Python多线程获取返回值代码实例
Feb 17 Python
Pytorch 卷积中的 Input Shape用法
Jun 29 Python
Python-openCV开运算实例
Jul 05 Python
python3.5的包存放的具体路径
Aug 16 Python
Django celery异步任务实现代码示例
Nov 26 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
第1次亲密接触PHP5(1)
2006/10/09 PHP
PHP简洁函数小结
2011/08/12 PHP
PHP中使用register_shutdown_function函数截获fatal error示例
2015/04/21 PHP
详谈symfony window下的安装 安装时候出现的问题以及解决方法
2017/09/28 PHP
JavaScript 变量命名规则
2009/09/23 Javascript
解析javascript 浏览器关闭事件
2013/07/08 Javascript
基于MVC3方式实现下拉列表联动(JQuery)
2013/09/02 Javascript
文本框文本自动补全效果示例分享
2014/01/19 Javascript
JavaScript实现的使用键盘控制人物走动实例
2014/08/27 Javascript
js自定义回调函数
2015/12/13 Javascript
一篇看懂vuejs的状态管理神器 vuex状态管理模式
2017/04/20 Javascript
JS触摸事件、手势事件详解
2017/05/04 Javascript
JavaScript变量作用域_动力节点Java学院整理
2017/06/27 Javascript
javaScript实现复选框全选反选事件详解
2020/11/20 Javascript
使用ECharts实现状态区间图
2018/10/25 Javascript
webpack4.x下babel的安装、配置及使用详解
2019/03/07 Javascript
详解JavaScript的数据类型以及数据类型的转换
2019/04/20 Javascript
JS实现图片切换特效
2019/12/23 Javascript
JS前端模块化原理与实现方法详解
2020/03/17 Javascript
js+canvas实现刮刮奖功能
2020/09/13 Javascript
JavaScript 绘制饼图的示例
2021/02/19 Javascript
实例解析Python的Twisted框架中Deferred对象的用法
2016/05/25 Python
详解Python读取配置文件模块ConfigParser
2017/05/11 Python
Python之关于类变量的两种赋值区别详解
2020/03/12 Python
Python做图像处理及视频音频文件分离和合成功能
2020/11/24 Python
HTML5不支持标签和新增标签详解
2016/06/27 HTML / CSS
KIKO MILANO荷兰网上商店:意大利专业化妆品品牌
2017/05/12 全球购物
Bose法国官网:购买耳机、扬声器、家庭影院、专业音响
2017/12/21 全球购物
澳大利亚在线家具店:Luxo Living
2019/03/24 全球购物
Camille Jewelry官网:现代女性时尚首饰
2019/07/07 全球购物
基层工作经历证明
2014/01/13 职场文书
毕业设计说明书
2014/05/07 职场文书
管理标语大全
2014/06/24 职场文书
2015年初中元旦晚会活动总结
2014/11/28 职场文书
JavaScript继承的三种方法实例
2021/05/12 Javascript
微软官方消息,在 2023 年 4 月 11 日之后微软将不再为 Office 2013 和 Skype for Business 2015 提供安全更新
2022/04/21 数码科技