這期內容當中小編將會給大家帶來有關使用py-spy解決scrapy卡死如何解決,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
背景
在使用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導致的。
接下來進行進一步確認,再按4,按TotalTIme 所有子函數執行時間總和進行排序,可以看到是在process_item和download,upload_image這些主流程函數的執行時間比較長,這一步是先把圖片下載到本地,然后上傳到靜床,看來是下載這步從網絡中read數據時出現了問題,進一步追蹤代碼。
看下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卡死如何解決了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。