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调用windows api锁定计算机示例
Apr 17 Python
python使用正则表达式提取网页URL的方法
May 26 Python
使用Python实现从各个子文件夹中复制指定文件的方法
Oct 25 Python
python,Django实现的淘宝客登录功能示例
Jun 12 Python
如何用Python来搭建一个简单的推荐系统
Aug 07 Python
django写用户登录判定并跳转制定页面的实例
Aug 21 Python
详解python3中用HTMLTestRunner.py报ImportError: No module named 'StringIO'如何解决
Aug 27 Python
Python全局锁中如何合理运用多线程(多进程)
Nov 06 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
Feb 22 Python
如何使用 Flask 做一个评论系统
Nov 27 Python
使用豆瓣源来安装python中的第三方库方法
Jan 26 Python
python实现腾讯滑块验证码识别
Apr 27 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
增加反向链接的101个方法 站长推荐
2007/01/31 PHP
PHP中如何判断AJAX提交的数据
2012/02/05 PHP
php实现用于计算执行时间的类实例
2015/04/18 PHP
php获取网站百度快照日期的方法
2015/07/29 PHP
PHP实现的只保留字符串首尾字符功能示例【隐藏部分字符串】
2019/03/11 PHP
关于 byval 与 byref 的区别分析总结
2007/10/08 Javascript
ext读取两种结构的xml的代码
2008/11/05 Javascript
拥抱模块化的JavaScript
2012/03/07 Javascript
页面使用密码保护代码
2013/04/10 Javascript
jQuery焦点图切换特效插件封装实例
2013/08/18 Javascript
JQuery中clone方法复制节点
2015/05/18 Javascript
JS 终止执行的实现方法
2016/11/24 Javascript
浅谈Nodejs中的作用域问题
2016/12/26 NodeJs
JavaScript实现元素滚动条到达一定位置循环追加内容
2017/12/28 Javascript
深入浅析Vue中的 computed 和 watch
2018/06/06 Javascript
详解React之父子组件传递和其它一些要点
2018/06/25 Javascript
详解微信小程序开发用户授权登陆
2019/04/24 Javascript
javascript贪吃蛇游戏设计与实现
2020/09/17 Javascript
vue3.0中setup使用(两种用法)
2020/12/02 Vue.js
Python 字典dict使用介绍
2014/11/30 Python
Python中的字典与成员运算符初步探究
2015/10/13 Python
Python中Numpy包的安装与使用方法简明教程
2018/07/03 Python
记一次python 内存泄漏问题及解决过程
2018/11/29 Python
python实现诗歌游戏(类继承)
2019/02/26 Python
python 图像处理画一个正弦函数代码实例
2019/09/10 Python
Python图像阈值化处理及算法比对实例解析
2020/06/19 Python
HTML5安全介绍之内容安全策略(CSP)简介
2012/07/10 HTML / CSS
无谷物狗粮:Pooch & Mutt
2018/05/23 全球购物
美国性感内衣店:Yandy
2018/06/12 全球购物
俄罗斯名牌服装网上商店:UNIQUE FABRIC
2019/07/25 全球购物
《跨越海峡的生命桥》教学反思
2014/02/24 职场文书
学习雷锋精神心得体会范文
2014/03/12 职场文书
2014业务员年终工作总结
2014/12/09 职场文书
物业项目经理岗位职责
2015/04/01 职场文书
干部考核工作总结
2015/08/12 职场文书
《搭石》教学反思
2016/02/18 职场文书