2

私はPythonに不慣れで、さらにツイストに不慣れです。ツイストを使用して数十万のファイルをダウンロードしようとしていますが、エラーバックを追加しようとして問題が発生しています。ダウンロードが失敗した場合、不正なURLを印刷したいのですが。エラーをスローするために、意図的にURLのスペルを間違えました。ただし、私が持っているコードはハングし、Pythonは終了しません(errback呼び出しを削除すると正常に終了します)。

また、各ファイルを個別に処理するにはどうすればよいですか?私の理解では、すべてが完了すると「終了」と呼ばれます。ダウンロード時に各ファイルをgzipで圧縮して、メモリから削除したいと思います。

これが私が持っているものです:

    urls = [
 'http://www.python.org', 
 'http://stackfsdfsdfdsoverflow.com', # misspelled on purpose to generate an error
 'http://www.twistedmatrix.com', 
 'http://www.google.com',
 'http://launchpad.net',
 'http://github.com',
 'http://bitbucket.org',
]

def finish(results):
    for result in results:
        print 'GOT PAGE', len(result), 'bytes'
    reactor.stop() 
def print_badurls(err):
    print err # how do I just print the bad url????????

waiting = [client.getPage(url) for url in urls]
defer.gatherResults(waiting).addCallback(finish).addErrback(print_badurls)

reactor.run() 
4

1 に答える 1

2

PythonとTwistedへようこそ!

貼り付けたコードにはいくつか問題があります。一度に1つずつ説明します。

まず、何千ものURLをダウンロードしたい場合で、urlsリストに何千ものアイテムが含まれる場合は、次の行になります。

waiting = [client.getPage(url) for url in urls]

問題を引き起こすでしょう。リスト内のすべてのページを同時にダウンロードしてみませんか?デフォルトでは、通常、Twistedで行うことは同時に発生するため、このループはurlsリスト内のすべてのURLのダウンロードを一度に開始します。ほとんどの場合、これは機能しません。DNSサーバーはドメインルックアップ要求の一部をドロップし、DNSクライアントはドメインルックアップ応答の一部をドロップします。取得したアドレスへのTCP接続の試行は、まだ使用可能なネットワークリソースをめぐって競合し、一部のアドレスはタイムアウトになります。残りの接続はすべて細流化され、数十またはおそらく数百の異なるダウンロード間で利用可能な帯域幅を共有します。

代わりに、同時実行の程度を一度に10または20ダウンロードに制限することをお勧めします。しばらく前に、これに対する1つのアプローチについてブログに書きました。

次に、渡されたが失敗して発砲するとすぐに発砲gatherResultsするを返します。したがって、いずれかが失敗するとすぐに、おそらく上記の問題の1つが原因で、ドメインが期限切れになったため、Webサーバーがダウンしたため、または不幸な一時的なネットワーク状態が原因で、不合格。 スキップされ、単一の失敗した呼び出しを説明するエラーで呼び出されます。Deferred Deferredclient.getPage(url)DeferredgatherResultsfinishprint_badurlsgetPage

Deferred個々のHTTPリクエストからの失敗を処理するには、コールバックとエラーバックを呼び出しから返されたに追加しますgetPage。これらのコールバックとエラーバックを追加した後、を使用して、すべてのダウンロードダウンロード結果の処理が完了するdefer.gatherResultsのを待つことができます。

第三に、このために高レベルのツールの使用を検討することをお勧めします-scrapyは、この種のアプリケーションに多くのクールで便利なヘルパーを提供するWebクロールフレームワーク(Twistedに基づく)です。

于 2012-10-07T23:18:39.777 に答える