使用py-spy解决scrapy卡死的问题方法


Posted in Python onSeptember 29, 2020

背景

在使用scrapy爬取东西的时候,使用crontab定时的启动爬虫,但是发现机器上经常产生很多卡死的scrapy进程,一段时间不管的话,会导致有10几个进程都卡死在那,并且会导致数据产出延迟。

问题定位

使用py-spy这个非常好用的python性能分析工具来进行排查,py-spy可以查看一个python进程函数调用用时,类似unix下的top命令。所以我们用这个工具看看是什么函数一直在执行。

首先安装这个工具

pip install py-spy

用py-spy看看scrapy哪个函数执行时间长

# 先找到这个卡死的scrapy进程的pid
ps -ef |grep scrapy 
# 启动 py-spy 观察这进程
py-spy top --pid 53424

首先我们按3,按OwnTime进行排序,这个表示函数自身执行的时间,可以看到read这个函数执行的时间最长,那看来是IO导致的,程序中的IO行为就是读写磁盘和网络IO,磁盘读写一般不会有问题,所以初步定位是网络IO导致的。

使用py-spy解决scrapy卡死的问题方法

接下来进行进一步确认,再按4,按TotalTIme 所有子函数执行时间总和进行排序,可以看到是在process_item和download,upload_image这些主流程函数的执行时间比较长,这一步是先把图片下载到本地,然后上传到静床,看来是下载这步从网络中read数据时出现了问题,进一步追踪代码。

使用py-spy解决scrapy卡死的问题方法

看下download的函数的代码:

if filename == '':
      filename = os.path.basename(url)
    path = path + '/' + filename
    
    try:
      res = request.urlretrieve(url,filename=path)
      print(url,res)
      return path
    except Exception as e:
      print('download img failed')
      print(e)
      return False

可以看到用了urllib这个库里面request.urlretrieve函数,这个函数是用来下载文件的,去看看python官网文档的函数说明,发现里面没有超时时间这个参数,所以是由于没有超时时间,导致一直在read,进而使得进程卡死。

urllib.request.urlretrieve(url, filename=None,reporthook=None,data=None)

解决方案

使用另一种方式来下载图片,使用支持超时时间的urlopen函数,封装成一个自定义的url_retrieve,这样就不再会出现没有超时导致的卡死问题了。

def url_retrieve(self,url, path):
    r = request.urlopen(url, timeout=5)
    res = False
    with open(path,"wb") as f:
      res = f.write(r.read())
      f.flush()
      f.close()
    return res

到此这篇关于使用py-spy解决scrapy卡死的问题方法的文章就介绍到这了,更多相关scrapy卡死内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python生成pdf文件的方法
Aug 04 Python
Python中input和raw_input的一点区别
Oct 21 Python
浅谈Python实现Apriori算法介绍
Dec 20 Python
python3.5 email实现发送邮件功能
May 22 Python
Python 编程速成(推荐)
Apr 15 Python
简单了解python单例模式的几种写法
Jul 01 Python
如何使用Python实现斐波那契数列
Jul 02 Python
django 做 migrate 时 表已存在的处理方法
Aug 31 Python
Python sklearn库实现PCA教程(以鸢尾花分类为例)
Feb 24 Python
浅谈pymysql查询语句中带有in时传递参数的问题
Jun 05 Python
Python基于mediainfo批量重命名图片文件
Dec 29 Python
深度学习详解之初试机器学习
Apr 14 Python
详解python对象之间的交互
Sep 29 #Python
python PIL模块的基本使用
Sep 29 #Python
Python 如何实现数据库表结构同步
Sep 29 #Python
scrapy-redis分布式爬虫的搭建过程(理论篇)
Sep 29 #Python
python ssh 执行shell命令的示例
Sep 29 #Python
Scrapy基于scrapy_redis实现分布式爬虫部署的示例
Sep 29 #Python
浅析python 字典嵌套
Sep 29 #Python
You might like
火车采集器 免费版使出收费版本功能实现原理
2009/09/17 PHP
解析PHP处理换行符的问题 \r\n
2013/06/13 PHP
php打开远程文件的方法和风险及解决方法
2013/11/12 PHP
php定界符
2014/06/19 PHP
php正则表达式使用方法整理集合
2020/01/31 PHP
关于JS字符串函数String.replace()
2013/04/07 Javascript
用innerhtml提高页面打开速度的方法
2013/08/02 Javascript
深入理解javascript动态插入技术
2013/11/12 Javascript
浅析JQuery中的html(),text(),val()区别
2014/09/01 Javascript
js用Date对象的setDate()函数对日期进行加减操作
2014/09/18 Javascript
Vue.js基础知识汇总
2016/04/27 Javascript
jQuery选择器基础入门教程
2016/05/10 Javascript
jQuery解析与处理服务器端返回xml格式数据的方法详解
2016/07/04 Javascript
js简单实现调整网页字体大小的方法
2016/07/23 Javascript
javascript 秒表计时器实现代码
2017/03/09 Javascript
详解.vue文件中监听input输入事件(oninput)
2017/09/19 Javascript
JS中this的指向以及call、apply的作用
2018/05/06 Javascript
在vue中使用SockJS实现webSocket通信的过程
2018/08/29 Javascript
三种Webpack打包方式(小结)
2018/09/19 Javascript
Vue项目实现换肤功能的一种方案分析
2019/08/28 Javascript
vue实现登录、注册、退出、跳转等功能
2020/12/23 Vue.js
[44:26]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第二局
2016/03/03 DOTA
Python中用startswith()函数判断字符串开头的教程
2015/04/07 Python
学习python之编写简单简单连接数据库并执行查询操作
2016/02/27 Python
详解Python的collections模块中的deque双端队列结构
2016/07/07 Python
基于python脚本实现软件的注册功能(机器码+注册码机制)
2016/10/09 Python
python使用pil进行图像处理(等比例压缩、裁剪)实例代码
2017/12/11 Python
Django 生成登陆验证码代码分享
2017/12/12 Python
Python中的正则表达式与JSON数据交换格式
2019/07/03 Python
python批量处理文件或文件夹
2020/07/28 Python
关于Python 解决Python3.9 pandas.read_excel(‘xxx.xlsx‘)报错的问题
2020/11/28 Python
党员的自我评价范文
2014/01/02 职场文书
自我介绍演讲稿
2014/01/15 职场文书
2015年会计工作总结范文
2015/05/26 职场文书
幼儿园见习总结
2015/06/23 职场文书
2015年六年级班主任工作总结
2015/10/15 职场文书