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 异常处理实例详解
Mar 12 Python
介绍Python的@property装饰器的用法
Apr 28 Python
python解决方案:WindowsError: [Error 2]
Aug 28 Python
Python 利用内置set函数对字符串和列表进行去重的方法
Jun 29 Python
Python对切片命名的实现方法
Oct 16 Python
Python多进程写入同一文件的方法
Jan 14 Python
pyqt5 实现工具栏文字图片同时显示
Jun 13 Python
通过PHP与Python代码对比的语法差异详解
Jul 10 Python
Django静态文件加载失败解决方案
Aug 26 Python
python time.strptime格式化实例详解
Feb 03 Python
解决tensorflow模型压缩的问题_踩坑无数,总算搞定
Mar 02 Python
python基于opencv批量生成验证码的示例
Apr 28 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
配置Apache2.2+PHP5+CakePHP1.2+MySQL5运行环境
2009/04/25 PHP
PHP中Array相关函数简介
2016/07/03 PHP
php中各种定义变量的方法小结
2017/10/18 PHP
自定义Laravel (monolog)日志位置,并增加请求ID的实现
2019/10/17 PHP
JQUERY 浏览器判断实现函数
2009/08/20 Javascript
JS 获取span标签中的值的代码 支持ie与firefox
2009/08/24 Javascript
Jquery Ajax 学习实例2 向页面发出请求 返回JSon格式数据
2010/03/15 Javascript
THREE.JS入门教程(5)你应当知道的十件事
2013/01/24 Javascript
JS 实现获取打开一个界面中输入的值
2013/03/19 Javascript
一个JS的日期格式化算法示例
2013/07/31 Javascript
javascript弹出层输入框(示例代码)
2013/12/11 Javascript
node.js入门教程
2014/06/01 Javascript
JS中的BOM应用
2018/02/02 Javascript
js构建二叉树进行数值数组的去重与优化详解
2018/03/26 Javascript
父组件中vuex方法更新state子组件不能及时更新并渲染的完美解决方法
2018/04/25 Javascript
简述vue-cli中chainWebpack的使用方法
2019/07/30 Javascript
ES11新增的这9个新特性,你都掌握了吗
2020/10/15 Javascript
Python类的多重继承问题深入分析
2014/11/09 Python
django通过ajax发起请求返回JSON格式数据的方法
2015/06/04 Python
node.js获取参数的常用方法(总结)
2017/05/29 Python
Python实现判断一个字符串是否包含子串的方法总结
2017/11/21 Python
Django uwsgi Nginx 的生产环境部署详解
2019/02/02 Python
python如何实现复制目录到指定目录
2020/02/13 Python
k-means 聚类算法与Python实现代码
2020/06/01 Python
Jupyter Notebook 远程访问配置详解
2021/01/11 Python
介绍一下.net和Java的特点和区别
2012/09/26 面试题
过程装备与控制工程专业个人的求职信
2013/12/01 职场文书
大学毕业感言50字
2014/02/07 职场文书
小学毕业感言300字
2014/02/19 职场文书
党员公开承诺书内容
2014/05/20 职场文书
慈善捐赠倡议书
2014/08/30 职场文书
2014年信贷员工作总结
2014/11/18 职场文书
十八大观后感
2015/06/12 职场文书
爱国影片观后感
2015/06/18 职场文书
Python字符串对齐方法使用(ljust()、rjust()和center())
2021/04/26 Python
MybatisPlus EntityWrapper如何自定义SQL
2022/03/22 Java/Android