py-spyを使ってscrapyカードの融通がきかない問題の方法を解決します。
背景
scrapyを使ってものをはう時、crontabのタイミングで爬虫剤を起動しますが、機械には多くのカードが死んでいるscrapyプロセスが発生しています。しばらくの間放置していると、10個のプロセスがあれで死んでしまい、データの出力が遅れてしまいます。
問題の位置づけ
py-spyという非常に使いやすいpython性能分析ツールを使って、排他調査を行います。py-spyはpythonプロセス関数の呼び出し用を確認できます。unixの下のtopコマンドのようです。このツールを使って、どの関数がずっと実行されているかを確認します。
まずこのツールをインストールします。
これからさらに確認して、4を押して、TotalTImeのすべてのサブ関数の実行時間の総和によって並べ替えて、process_であることが見えます。itemとdownload、uplad_imageこれらの主流のプロセス関数の実行時間は比較的に長いですが、このステップはまず画像を地元にダウンロードしてから静的なベッドにアップロードします。このステップはネットワークからreadデータをダウンロードする時に問題が発生しました。コードをさらに追跡します。
ダウンロードの関数のコードを見てください。
別の方法で画像をダウンロードします。タイムアウト時間対応のurlopen関数を使って、カスタムurl cuuにパッケージ化します。retrieve、このようにもうタイムアウトの招くカードがない問題が現れませんでした。
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カードの死の内容は以前の文章を検索したり、次の関連記事を見たりしてください。これからもよろしくお願いします。