4

mechanize を使用して別の Web サイトからデータを取得する Python コードを少し作成しています。Web サイトが複雑なため、コードが完了するまでに 10 ~ 30 秒かかります。それは、数ページなどを介して処理する必要があります。

このコードをかなり頻繁に呼び出す予定です。サーバーに大きな負荷をかけることなく、このようなものを実装する最善の方法を考えています。私はPythonにかなり慣れていないので、言語がどのように機能するかわかりません。

コードが 1 つの要求の処理中に別のユーザーがコードを呼び出した場合、コードの 2 つのインスタンスを同時に実行できますか? このようなものを実装するより良い方法はありますか?

サーバーに負担をかけることなく、多額のタスクを完了できるように設計したいと考えています。

4

3 に答える 3

1

私のデータ取得スクリプトはすべて、サーバーの負荷を最小限に抑えるためにキャッシュを使用しています。「If-Modified-Since」、「If-None-Match」、「Accept-Encoding:gzip」などのHTTPツールを必ず使用してください。

また、リクエストを並行して実行できるように、マルチプロセッシングモジュールの使用を検討してください。

これが私のダウンローダースクリプトからの抜粋です:

def urlretrieve(url, filename, cache, lock=threading.Lock()):
    'Read contents of an open url, use etags and decompress if needed'    

    request = urllib2.Request(url)
    request.add_header('Accept-Encoding', 'gzip')
    with lock:
        if ('etag ' + url) in cache:
            request.add_header('If-None-Match', cache['etag ' + url])
        if ('date ' + url) in cache:
            request.add_header('If-Modified-Since', cache['date ' + url])

    try:
        u = urllib2.urlopen(request)
    except urllib2.HTTPError as e:
        return Response(e.code, e.msg, False, False)
    content = u.read()
    u.close()

    compressed = u.info().getheader('Content-Encoding') == 'gzip'
    if compressed:
        content = gzip.GzipFile(fileobj=StringIO.StringIO(content), mode='rb').read()

    written = writefile(filename, content) 

    with lock:
        etag = u.info().getheader('Etag')
        if etag:
            cache['etag ' + url] = etag
        timestamp = u.info().getheader('Date')
        if timestamp:
            cache['date ' + url] = timestamp

    return Response(u.code, u.msg, compressed, written)

キャッシュは、永続的な辞書であるshelveのインスタンスです。

ダウンローダーの呼び出しは、マルチプロセッシングプールインスタンスでimap_unordered()と並列化されます。

于 2012-08-01T15:39:46.533 に答える
0

基本的な答えは、「重要なリソース(データベースなど)を共有しない限り、プログラムのインスタンスをいくつでも実行できる」というものです。

実際には、「マルチプロセッシングモジュール」を使用し、同時実行性を処理して破損した状態やデッドロックを回避するようにアプリケーションを適切に設計する必要があることがよくあります。

ちなみに、マルチプロセスアプリの設計は、StackOverflowに関する簡単な質問の範囲を超えています...

于 2012-08-01T15:37:15.933 に答える
0

一度に複数のPythonプロセスを実行できます。サーバーに過度の負荷をかけることに関しては、常に1つのインスタンスのみを実行するか、他の数のプロセス(たとえば、2つ)を実行することによってのみ軽減できます。これを実現するために、ロックファイルまたはある種のシステムフラグ、ミューテックスなどを使用することを検討できます。

ただし、過度の使用を制限する最善の方法は、同時に実行されるタスクの数を制限することです。

于 2012-08-01T15:35:06.133 に答える