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 相关文章推荐
win10系统中安装scrapy-1.1
Jul 03 Python
python决策树之CART分类回归树详解
Dec 20 Python
python调用百度语音识别api
Aug 30 Python
Python中几种属性访问的区别与用法详解
Oct 10 Python
Python实现高斯函数的三维显示方法
Dec 29 Python
详解如何用python实现一个简单下载器的服务端和客户端
Oct 28 Python
python的time模块和datetime模块实例解析
Nov 29 Python
python3实现在二叉树中找出和为某一值的所有路径(推荐)
Dec 26 Python
python+requests接口压力测试500次,查看响应时间的实例
Apr 30 Python
Django前后端分离csrf token获取方式
Dec 25 Python
Python 制作自动化翻译工具
Apr 25 Python
python画条形图的具体代码
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
关于拼配咖啡,你要知道
2021/03/03 咖啡文化
php下过滤HTML代码的函数
2007/12/10 PHP
php日历[测试通过]
2008/03/27 PHP
PHP7 字符串处理机制修改
2021/03/09 PHP
IE6/7/8/9不支持exec的简写方式
2011/05/25 Javascript
JS Map 和 List 的简单实现代码
2013/07/08 Javascript
js取float型小数点后两位数的方法
2014/01/18 Javascript
Jquery实现控件的隐藏和显示实例
2014/02/08 Javascript
模拟用户点击弹出新页面不会被浏览器拦截
2014/04/08 Javascript
javascript基于DOM实现权限选择实例分析
2015/05/14 Javascript
JavaScript实现将UPC转换成ISBN的方法
2015/05/26 Javascript
RequireJS简易绘图程序开发
2016/10/28 Javascript
js对字符串进行编码的方法总结(推荐)
2016/11/10 Javascript
JavaScript实现公历转农历功能示例
2017/02/13 Javascript
详解React Native开源时间日期选择器组件(react-native-datetime)
2017/09/13 Javascript
浅谈es6中export和export default的作用及区别
2018/02/07 Javascript
一篇文章带你浅入webpack的DLL优化打包
2020/02/20 Javascript
深入解析微信小程序开发中遇到的几个小问题
2020/07/11 Javascript
Vue router安装及使用方法解析
2020/12/02 Vue.js
解决vue项目本地启动时无法携带cookie的问题
2021/02/06 Vue.js
[01:02:20]Mineski vs TNC 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
在Python中的Django框架中进行字符串翻译
2015/07/27 Python
PYTHON发送邮件YAGMAIL的简单实现解析
2019/10/28 Python
Pytorch: 自定义网络层实例
2020/01/07 Python
Python爬虫如何破解JS加密的Cookie
2020/11/19 Python
python+appium+yaml移动端自动化测试框架实现详解
2020/11/24 Python
python爬虫破解字体加密案例详解
2021/03/02 Python
长曲棍球装备:Lacrosse Monkey
2020/12/02 全球购物
求职信模版
2013/11/30 职场文书
社区端午节活动方案
2014/01/28 职场文书
2014年五一活动策划方案
2014/03/15 职场文书
财产公证书
2014/04/10 职场文书
2014年国庆标语
2014/06/30 职场文书
中学生爱国演讲稿
2014/09/05 职场文书
庆祝教师节标语
2014/10/09 职场文书
少先队工作总结2015
2015/05/13 职场文书