使用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代码
Mar 13 Python
Python使用ftplib实现简易FTP客户端的方法
Jun 03 Python
python脚本监控docker容器
Apr 27 Python
Python实现网络端口转发和重定向的方法
Sep 19 Python
Python 基础教程之str和repr的详解
Aug 20 Python
python MysqlDb模块安装及其使用详解
Feb 23 Python
Python3.4学习笔记之常用操作符,条件分支和循环用法示例
Mar 01 Python
Python利用requests模块下载图片实例代码
Aug 12 Python
Python 类属性与实例属性,类对象与实例对象用法分析
Sep 20 Python
Python实现平行坐标图的绘制(plotly)方式
Nov 22 Python
python文件编写好后如何实践
Jul 07 Python
Pytorch 扩展Tensor维度、压缩Tensor维度的方法
Sep 09 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
编译问题
2006/10/09 PHP
PHP三层结构(上) 简单三层结构
2010/07/04 PHP
关于PHP的相似度计算函数:levenshtein的使用介绍
2013/04/15 PHP
PHP5中Cookie与 Session使用详解
2013/04/30 PHP
PHP使用get_headers函数判断远程文件是否存在的方法
2014/11/28 PHP
thinkPHP5框架实现基于ajax的分页功能示例
2018/06/12 PHP
基于jquery的3d效果实现代码
2011/03/23 Javascript
js中substring和substr的详细介绍与用法
2013/08/29 Javascript
为开发者准备的10款最好的jQuery日历插件
2014/02/04 Javascript
jQuery 3 中的新增功能汇总介绍
2016/06/12 Javascript
js实时获取窗口大小变化的实例代码
2016/11/18 Javascript
angularJS 指令封装回到顶部示例详解
2017/01/22 Javascript
JS实现含有中文字符串的友好截取功能分析
2017/03/13 Javascript
vue实现div拖拽互换位置
2020/07/29 Javascript
JavaScript 实现下雪特效的示例代码
2020/09/09 Javascript
[03:40]DOTA2亚洲邀请赛小组赛第二日 赛事回顾
2015/01/31 DOTA
[01:04:31]DOTA2-DPC中国联赛定级赛 iG vs Magma BO3第二场 1月8日
2021/03/11 DOTA
Python提示[Errno 32]Broken pipe导致线程crash错误解决方法
2014/11/19 Python
Python实现的ini文件操作类分享
2014/11/20 Python
简单了解python模块概念
2018/01/11 Python
Python实现程序判断季节的代码示例
2019/01/28 Python
python实现杨氏矩阵查找
2019/03/02 Python
Python自动抢红包教程详解
2019/06/11 Python
python中selenium操作下拉滚动条的几种方法汇总
2019/07/14 Python
Python中调用其他程序的方式详解
2019/08/06 Python
Python2和3字符编码的区别知识点整理
2019/08/08 Python
python爬虫 urllib模块url编码处理详解
2019/08/20 Python
Python PyQt5模块实现窗口GUI界面代码实例
2020/05/12 Python
浅谈keras中的keras.utils.to_categorical用法
2020/07/02 Python
python3定位并识别图片验证码实现自动登录功能
2021/01/29 Python
美国椅子和沙发制造商:La-Z-Boy
2020/10/25 全球购物
药剂专业求职信
2014/06/20 职场文书
学习教师敬业奉献模范事迹材料思想汇报
2014/09/19 职场文书
个人公司授权委托书范本
2014/10/12 职场文书
企业承诺书格式范文
2015/04/28 职场文书
公司备用金管理制度
2015/08/04 职场文书