使用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 相关文章推荐
在Django中编写模版节点及注册标签的方法
Jul 20 Python
python简单商城购物车实例代码
Mar 15 Python
python实现猜数字小游戏
Mar 24 Python
python数据批量写入ScrolledText的优化方法
Oct 11 Python
python日期相关操作实例小结
Jun 24 Python
python读写csv文件方法详细总结
Jul 05 Python
Python for循环及基础用法详解
Nov 08 Python
Python requests获取网页常用方法解析
Feb 20 Python
对Python 字典元素进行删除的方法
Jul 31 Python
Python lxml库的简单介绍及基本使用讲解
Dec 22 Python
Python爬虫爬取微博热搜保存为 Markdown 文件的源码
Feb 22 Python
用python实现监控视频人数统计
May 21 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
Terran剧情介绍
2020/03/14 星际争霸
基于HTTP长连接的"服务器推"技术的php 简易聊天室
2009/10/31 PHP
PHP获取当前url的具体方法全面解析
2013/11/26 PHP
PHP实现补齐关闭的HTML标签
2016/03/22 PHP
PHP中常用的魔术方法
2017/04/28 PHP
PHP实现笛卡尔积算法的实例讲解
2019/12/22 PHP
jquery文字上下滚动的实现方法
2013/03/22 Javascript
jquery清空表单数据示例分享
2014/02/13 Javascript
nodejs开发环境配置与使用
2014/11/17 NodeJs
javascript+html5实现仿flash滚动播放图片的方法
2015/04/27 Javascript
基于gulp合并压缩Seajs模块的方式说明
2016/06/14 Javascript
Vue.js组件使用开发实例教程
2016/11/01 Javascript
Layui table 组件的使用之初始化加载数据、数据刷新表格、传参数
2017/09/11 Javascript
Angular数据绑定机制原理
2018/04/17 Javascript
微信小程序+云开发实现欢迎登录注册
2019/05/24 Javascript
微信小程序防止多次点击跳转和防止表单组件输入内容多次验证功能(函数防抖)
2019/09/19 Javascript
[45:16]完美世界DOTA2联赛循环赛 IO vs FTD BO2第二场 11.05
2020/11/06 DOTA
[52:52]完美世界DOTA2联赛PWL S3 LBZS vs access 第一场 12.10
2020/12/13 DOTA
Python解析树及树的遍历
2016/02/03 Python
Python 实现随机数详解及实例代码
2017/04/15 Python
Python 关于反射和类的特殊成员方法
2017/09/14 Python
python生成excel的实例代码
2017/11/08 Python
Python实现可设置持续运行时间、线程数及时间间隔的多线程异步post请求功能
2018/01/11 Python
pandas 条件搜索返回列表的方法
2018/10/30 Python
python编写计算器功能
2019/10/25 Python
python3实现用turtle模块画一棵随机樱花树
2019/11/21 Python
关于python中plt.hist参数的使用详解
2019/11/28 Python
Python实现序列化及csv文件读取
2020/01/19 Python
python一些性能分析的技巧
2020/08/30 Python
Oral-B荷兰:牙医最推荐的品牌
2020/02/25 全球购物
开会迟到检讨书
2014/01/08 职场文书
酒店辞职书怎么写
2015/02/26 职场文书
四群教育工作总结
2015/08/10 职场文书
董事长秘书工作总结
2015/08/14 职场文书
2019朋友新婚祝福语精选
2019/10/10 职场文书
聊聊Python中关于a=[[]]*3的反思
2021/06/02 Python