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中变量交换的例子
Aug 25 Python
Django Highcharts制作图表
Aug 27 Python
利用python将xml文件解析成html文件的实现方法
Dec 22 Python
批量将ppt转换为pdf的Python代码 只要27行!
Feb 26 Python
python实现搜索文本文件内容脚本
Jun 22 Python
使用python读取.text文件特定行的数据方法
Jan 28 Python
对Python的交互模式和直接运行.py文件的区别详解
Jun 29 Python
Python shelve模块实现解析
Aug 28 Python
python3实现高效的端口扫描
Aug 31 Python
Python Collatz序列实现过程解析
Oct 12 Python
python几种常用功能实现代码实例
Dec 25 Python
Python创建文件夹与文件的快捷方法
Dec 08 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
PHP 字符串加密函数(在指定时间内加密还原字符串,超时无法还原)
2010/04/28 PHP
php学习之 数组声明
2011/06/09 PHP
PHP开发框架kohana3 自定义路由设置示例
2014/07/14 PHP
php文件下载处理方法分析
2015/04/22 PHP
总结PHP如何获取当前主机、域名、网址、路径、端口和参数等
2016/09/09 PHP
php使用PDO下exec()函数查询执行后受影响行数的方法
2017/03/28 PHP
Jquery ajaxsubmit上传图片实现代码
2010/11/04 Javascript
jQuery实现密保互斥问题解决方案
2013/08/16 Javascript
wap浏览自动跳转到wap页面的js代码
2014/05/17 Javascript
javascript实现网页中涉及的简易运动(改变宽高、透明度、位置)
2015/11/29 Javascript
使用JavaScript实现ajax的实例代码
2016/05/11 Javascript
PHP获取当前页面完整URL的方法
2016/12/02 Javascript
微信小程序 省市区选择器实例详解(附源码下载)
2017/01/05 Javascript
jQuery动态移除和添加背景图片的方法详解
2017/03/07 Javascript
详解webpack模块加载器兼打包工具
2018/09/11 Javascript
layui2.0使用table+laypage实现真分页
2019/07/27 Javascript
Vuex modules模式下mapState/mapMutations的操作实例
2019/10/17 Javascript
React Native登录之指纹登录篇的示例代码
2020/11/03 Javascript
Python中MYSQLdb出现乱码的解决方法
2014/10/11 Python
Python使用xlrd模块操作Excel数据导入的方法
2015/05/26 Python
Python实现FTP上传文件或文件夹实例(递归)
2017/01/16 Python
Python实现螺旋矩阵的填充算法示例
2017/12/28 Python
详解如何将python3.6软件的py文件打包成exe程序
2018/10/09 Python
详解Python中的测试工具
2019/06/09 Python
Django 开发调试工具 Django-debug-toolbar使用详解
2019/07/23 Python
django框架使用views.py的函数对表进行增删改查内容操作详解【models.py中表的创建、views.py中函数的使用,基于对象的跨表查询】
2019/12/12 Python
python Popen 获取输出,等待运行完成示例
2019/12/30 Python
Python本地及虚拟解释器配置过程解析
2020/10/13 Python
玩转CSS3色彩
2010/01/16 HTML / CSS
基于HTML5的齿轮动画特效
2016/02/29 HTML / CSS
匡威帆布鞋美国官网:Converse美国
2016/08/22 全球购物
Sunglasses Shop英国:欧洲领先的太阳镜在线供应商之一
2018/09/19 全球购物
电脑饰品店的创业计划书
2014/01/21 职场文书
养成教育经验材料
2014/05/26 职场文书
邓小平理论心得体会
2014/09/09 职场文书
vue基于Teleport实现Modal组件
2021/05/31 Vue.js