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、uplad_imageこれらの主流のプロセス関数の実行時間は比較的に長いですが、このステップはまず画像を地元にダウンロードしてから静的なベッドにアップロードします。このステップはネットワークからreadデータをダウンロードする時に問題が発生しました。コードをさらに追跡します。
在这里插入图片描述
ダウンロードの関数のコードを見てください。

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 cuuにパッケージ化します。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カードの死の内容は以前の文章を検索したり、次の関連記事を見たりしてください。これからもよろしくお願いします。