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写xml文件的操作实例
Oct 05 Python
python实现井字棋游戏
Mar 30 Python
Python数组遍历的简单实现方法小结
Apr 27 Python
Python黑魔法Descriptor描述符的实例解析
Jun 02 Python
单链表反转python实现代码示例
Feb 08 Python
对Python中for复合语句的使用示例讲解
Nov 01 Python
Python中利用aiohttp制作异步爬虫及简单应用
Nov 29 Python
python异步编程 使用yield from过程解析
Sep 25 Python
Pytorch的mean和std调查实例
Jan 02 Python
新年福利来一波之Python轻松集齐五福(demo)
Jan 20 Python
python安装及变量名介绍详解
Dec 12 Python
Python实现抖音热搜定时爬取功能
Mar 16 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数组排序函数合集 以及它们之间的联系分析
2013/06/27 PHP
JQuery与JSon实现的无刷新分页代码
2011/09/13 Javascript
JS鼠标事件大全 推荐收藏
2011/11/01 Javascript
javascript 文本框水印/占位符(watermark/placeholder)实现方法
2012/01/15 Javascript
js汉字转拼音实现代码
2013/02/06 Javascript
JS.elementGetStyle(element, style)应用示例
2013/09/24 Javascript
jQuery实现列表自动滚动循环滚动展示新闻
2014/08/22 Javascript
js图片卷帘门导航菜单特效代码分享
2015/09/10 Javascript
jQuery通过deferred对象管理ajax异步
2016/05/20 Javascript
AngularJS通过$location获取及改变当前页面的URL
2016/09/23 Javascript
javascript跨域请求包装函数与用法示例
2016/11/03 Javascript
Javascript之面向对象--接口
2016/12/02 Javascript
Move.js入门
2017/02/08 Javascript
Javascript中的async awai的用法
2017/05/17 Javascript
Agularjs妙用双向数据绑定实现手风琴效果
2017/05/26 Javascript
React Native 环境搭建的教程
2017/08/19 Javascript
form表单数据封装成json格式并提交给服务器的实现方法
2017/12/14 Javascript
fullpage.js最后一屏滚动方式
2018/02/06 Javascript
nodejs中密码加密处理操作详解
2018/03/20 NodeJs
最基础的Python的socket编程入门教程
2015/04/23 Python
python简单贪吃蛇开发
2019/01/28 Python
python设置随机种子实例讲解
2019/09/12 Python
利用python读取YUV文件 转RGB 8bit/10bit通用
2019/12/09 Python
python 实现将list转成字符串,中间用空格隔开
2019/12/25 Python
python对XML文件的操作实现代码
2020/03/27 Python
keras实现基于孪生网络的图片相似度计算方式
2020/06/11 Python
小学教师的自我评价范例
2013/10/31 职场文书
党的群众路线教育实践活动批评与自我批评
2014/02/16 职场文书
文明礼仪伴我行演讲稿
2014/05/12 职场文书
优秀班主任先进事迹材料
2014/12/16 职场文书
结婚保证书
2015/01/16 职场文书
事业单位财务人员岗位职责
2015/04/14 职场文书
2015医院个人工作总结范文
2015/05/21 职场文书
《半截蜡烛》教学反思
2016/02/19 职场文书
为什么阅读对所有年龄段的孩子都很重要?
2019/07/08 职场文书
threejs太阳光与阴影效果实例代码
2022/04/05 Javascript