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 相关文章推荐
PHP webshell检查工具 python实现代码
Sep 15 Python
python协程用法实例分析
Jun 04 Python
基于Python实现通过微信搜索功能查看谁把你删除了
Jan 27 Python
Python 专题二 条件语句和循环语句的基础知识
Mar 19 Python
python编写分类决策树的代码
Dec 21 Python
pycharm debug功能实现跳到循环末尾的方法
Nov 29 Python
Python读取Pickle文件信息并计算与当前时间间隔的方法分析
Jan 30 Python
scikit-learn线性回归,多元回归,多项式回归的实现
Aug 29 Python
节日快乐! Python画一棵圣诞树送给你
Dec 24 Python
pytorch  网络参数 weight bias 初始化详解
Jun 24 Python
python 实现单例模式的5种方法
Sep 23 Python
python单元测试之pytest的使用
Jun 07 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
IIS7.X配置PHP运行环境小结
2011/06/09 PHP
PHP实现简单数字分页效果
2015/07/26 PHP
php打包压缩文件之ZipArchive方法用法分析
2016/04/30 PHP
PHP转换文本框内容为HTML格式的方法
2016/07/20 PHP
jquery.validate使用攻略 第二部
2010/07/01 Javascript
初窥JQuery(二)事件机制(2)
2010/12/06 Javascript
jQuery图片的展开和收缩实现代码
2013/04/16 Javascript
JavaScript中实现PHP的打乱数组函数shuffle实例
2014/10/11 Javascript
jQuery中outerHeight()方法用法实例
2015/01/19 Javascript
jQuery实现锚点scoll效果实例分析
2015/03/10 Javascript
js简单工厂模式用法实例
2015/06/30 Javascript
jquery实现滑屏大图定时收缩为小banner图片的广告代码
2015/09/02 Javascript
jQuery+ajax简单实现文件上传的方法
2016/06/03 Javascript
微信小程序实现移动端滑动分页效果(ajax)
2017/06/13 Javascript
Vue中消息横向滚动时setInterval清不掉的问题及解决方法
2019/08/23 Javascript
解决antd的Form组件setFieldsValue的警告问题
2020/10/29 Javascript
[19:15]DK战队纪录片
2014/09/02 DOTA
python list语法学习(带例子)
2013/11/01 Python
haskell实现多线程服务器实例代码
2013/11/26 Python
使用PDB简单调试Python程序简明指南
2015/04/25 Python
全面了解Python的getattr(),setattr(),delattr(),hasattr()
2016/06/14 Python
Python 自动刷博客浏览量实例代码
2017/06/14 Python
python pandas 对series和dataframe的重置索引reindex方法
2018/06/07 Python
python+opencv+caffe+摄像头做目标检测的实例代码
2018/08/03 Python
查看端口并杀进程python脚本代码
2019/12/17 Python
Django 项目通过加载不同env文件来区分不同环境
2020/02/17 Python
Python实现Word文档转换Markdown的示例
2020/12/22 Python
Stührling手表官方网站:男女高品质时尚手表的领先零售商
2021/01/07 全球购物
应届生英语教师求职信
2013/11/05 职场文书
毕业生的自我评价
2013/12/30 职场文书
《美丽的彩虹》教学反思
2014/02/25 职场文书
团队拓展活动总结
2014/08/27 职场文书
2015年园林绿化工作总结
2015/05/23 职场文书
信仰纪录片观后感
2015/06/08 职场文书
使用vue-element-admin框架从后端动态获取菜单功能的实现
2021/04/29 Vue.js
聊聊CSS粘性定位sticky案例解析
2022/06/01 HTML / CSS