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与php实现分割文件代码
Mar 06 Python
Python实现希尔排序算法的原理与用法实例分析
Nov 23 Python
python opencv 图像尺寸变换方法
Apr 02 Python
Python遍历numpy数组的实例
Apr 04 Python
使用Python和Scribus创建一个RGB立方体的方法
Jul 17 Python
python保存log日志,实现用log日志画图
Dec 24 Python
pytorch中的transforms模块实例详解
Dec 31 Python
python使用html2text库实现从HTML转markdown的方法详解
Feb 21 Python
更新升级python和pip版本后不生效的问题解决
Apr 17 Python
python 实现端口扫描工具
Dec 18 Python
浅析Python中的套接字编程
Jun 22 Python
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
Apr 20 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
MySQL中create table语句的基本语法是
2007/01/15 PHP
PHP两种去掉数组重复值的方法比较
2014/06/19 PHP
PHP使用gmdate实现将一个UNIX 时间格式化成GMT文本的方法
2015/03/19 PHP
实例讲解php数据访问
2016/05/09 PHP
Yii安装与使用Excel扩展的方法
2016/07/13 PHP
php+ajax实现仿百度查询下拉内容功能示例
2017/10/20 PHP
20款非常优秀的 jQuery 工具提示插件 推荐
2012/07/15 Javascript
jQuery快速上手:写jQuery与直接写JS的区别详细解析
2013/08/26 Javascript
轻松创建nodejs服务器(3):代码模块化
2014/12/18 NodeJs
JS获取和修改元素样式的实例代码
2016/08/06 Javascript
nodejs制作爬虫实现批量下载图片
2017/05/19 NodeJs
[js高手之路]原型式继承与寄生式继承详解
2017/08/28 Javascript
JS实现仿微信支付弹窗功能
2018/06/25 Javascript
jQuery表单元素过滤选择器用法实例分析
2019/02/20 jQuery
tweenjs缓动算法的使用实例分析
2019/08/26 Javascript
vue 百度地图(vue-baidu-map)绘制方向箭头折线实例代码详解
2020/04/28 Javascript
[49:20]2014 DOTA2国际邀请赛中国区预选赛5.21 CIS VS TongFu
2014/05/22 DOTA
[01:01:22]VGJ.S vs OG 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
Android分包MultiDex策略详解
2017/10/30 Python
Python内置模块ConfigParser实现配置读写功能的方法
2018/02/12 Python
浅谈python配置与使用OpenCV踩的一些坑
2018/04/02 Python
浅谈Pycharm中的Python Console与Terminal
2019/01/17 Python
Atom Python 配置Python3 解释器的方法
2019/08/28 Python
基于python爬取链家二手房信息代码示例
2020/10/21 Python
Django执行源生mysql语句实现过程解析
2020/11/12 Python
菲律宾酒店预订网站:Hotels.com菲律宾
2017/07/12 全球购物
香奈儿美国官网:CHANEL美国
2020/05/20 全球购物
魅力教师事迹材料
2014/01/10 职场文书
驾驶员岗位职责
2014/01/29 职场文书
党员学习群众路线心得体会
2014/11/04 职场文书
2014年化妆品销售工作总结
2014/12/01 职场文书
2015年教师节演讲稿范文
2015/03/19 职场文书
公司财务经理岗位职责
2015/04/08 职场文书
离婚答辩状怎么写
2015/05/22 职场文书
SpringBoot实现quartz定时任务可视化管理功能
2021/08/30 Java/Android
分享几种python 变量合并方法
2022/03/20 Python