1

私は楽しみのためにPythonでダウンロードマネージャーを構築しています。サーバーへの接続はまだオンですが、サーバーからデータが送信されない場合があるため、(HTTPResponseの)メソッドを読み取ると永遠にブロックされます。これは、たとえば、自分の国以外にあるサーバーからダウンロードしたときに発生し、他の国への帯域幅が制限されています。

読み取りメソッドのタイムアウトを設定するにはどうすればよいですか (たとえば 2 分)?

ありがとう、ニル。

4

4 に答える 4

3

Python のバージョンに行き詰まっている場合< 2.6、1 つの (不完全だが使用可能な) 方法は次のとおりです。

import socket
socket.setdefaulttimeout(10.0)  # or whatever

を使い始める前にhttplib。ドキュメントはここにあり、Python 2.3 以降で利用可能であることが明確に述べられsetdefaulttimeoutています。この呼び出しを行ってから同じ関数を再度呼び出すまでに作成されたすべてのソケットは、10 秒のタイムアウトを使用します。以前のタイムアウト (なしを含む) を保存して、後で (別の で) 復元できるようにする場合は、新しいタイムアウトを設定する前にgetdefaulttimeoutを使用できますsetdefaulttimeout

これらの関数とイディオムは、Python を使用する古い高レベル ライブラリを使用する必要がある場合に非常に役立ちますがsocket、タイムアウトを設定する適切な方法がありません (もちろん、更新された高レベル ライブラリを使用することをお勧めしますhttplib。この場合は 2.6 またはサードパーティhttplib2に付属していますが、常に実行できるとは限らず、デフォルトのタイムアウト設定で遊ぶことが適切な回避策になる可能性があります)。

于 2010-04-04T00:27:51.087 に答える
2

HTTPConnectionの初期化中に設定する必要があります。

注: 古いバージョンの Python を使用している場合は、httplib2をインストールできます。多くの人が httplib の優れた代替手段と考えており、timeoutをサポートしています。
ただし、私はそれを使用したことはなく、ドキュメントやブログが何を言っているかを報告しているだけです.

于 2010-04-03T23:37:16.103 に答える
1

デフォルトのタイムアウトを設定すると、タイムアウト値のデータの受信を停止した場合にのみ中止するのではなく、大きい場合はダウンロードを早期に中止する可能性があります。HTTPlib2 はおそらく進むべき道です。

于 2010-08-30T18:02:49.500 に答える
-1

5年後ですが、うまくいけば、これは他の誰かを助けるでしょう...

私はこれを理解しようとして頭を悩ませていました。私の問題は、サーバーが破損したコンテンツを返すため、思ったよりも少ないデータを返すことでした.

適切に機能しているように見える厄介な解決策を思いつきました。ここに行きます:

# NOTE I directly disabling blocking is not necessary but it represents
# an important piece to the problem so I am leaving it here.
# http_response.fp._sock.socket.setblocking(0)
http_response.fp._sock.settimeout(read_timeout)
http_response.read(chunk_size)

: このソリューションは、通常の python ソケットを実装するpython requests ANYライブラリに対しても機能します (どれがすべてである必要がありますか?)。いくつかのレベルをさらに深くする必要があります。

resp.raw._fp.fp._sock.socket.setblocking()
resp.raw._fp.fp._sock.settimeout(read_timeout)
resp.raw.read(chunk_size)

これを書いている時点で、私は次のことを試していませんが、理論的にはうまくいくはずです:

resp = requests.get(some_url, stream=True)
resp.raw._fp.fp._sock.socket.setblocking()
resp.raw._fp.fp._sock.settimeout(read_timeout)
for chunk in resp.iter_content(chunk_size):
      # do stuff

説明

このSOの質問を読んで、socket.recvでタイムアウトを設定するときに、このアプローチに出くわしました

結局のところ、すべての http リクエストにはソケットがあります。httplib の場合、そのソケットは にありresp.raw._fp.fp._sock.socketます。これresp.raw._fp.fp._socksocket._fileobj(私は正直に詳しく調べていませんでした) であり、settimeoutメソッドが内部的にsocket属性に設定していると思います。

于 2015-12-03T06:50:09.430 に答える