5

http URL からローカル ファイルにファイルをダウンロードしようとしています。ファイルは十分に大きいので、ファイル全体を単一の巨大な文字列としてではなく、ダウンロードしてチャンクに保存したいと思いread()ます。write()

のインターフェースは、urllib.urlretrieve本質的に私が欲しいものです。ただし、経由でダウンロードするときにリクエストヘッダーを設定する方法がわかり urllib.urlretrieveません。これは、私が行う必要があることです。

を使用すると、そのオブジェクトurllib2を介してリクエスト ヘッダーを設定できます。ただし、ファイルをディスク上のパスに直接ダウンロードするためRequestの API は見当たりません。代わりに、ループを使用して返されたデータをチャンクで反復処理し、それらを自分でファイルに書き込み、完了したらチェックする必要があるようです。urllib2urlretrieve

urllib.urlretrieveのように機能するが、リクエストヘッダーを渡すことができる関数を構築する最良の方法は何でしょうか?

4

2 に答える 2

3

urllib2 を使用して独自の関数を作成することの害は何ですか?

import os
import sys
import urllib2

def urlretrieve(urlfile, fpath):
    chunk = 4096
    f = open(fpath, "w")
    while 1:
        data = urlfile.read(chunk)
        if not data:
            print "done."
            break
        f.write(data)
        print "Read %s bytes"%len(data)

リクエストオブジェクトを使用してヘッダーを設定する

request = urllib2.Request("http://www.google.com")
request.add_header('User-agent', 'Chrome XXX')
urlretrieve(urllib2.urlopen(request), "/tmp/del.html")
于 2010-01-08T15:53:49.750 に答える
2

urllib と urlretrieve を使用する場合は、サブクラスurllib.URLopener化し、そのaddheader()メソッドを使用してヘッダーを調整します (つまりaddheader('Accept', 'sound/basic')、urllib.addheader の docstring から取得しています)。

urllib で使用する URLopener をインストールするには、ドキュメントのurllib._urlopenerセクションの例を参照してください (アンダースコアに注意してください)。

import urllib

class MyURLopener(urllib.URLopener):
    pass # your override here, perhaps to __init__

urllib._urlopener = MyURLopener

ただし、質問のコメントに対するコメントを聞いて喜んでいます。から空の文字列を読み取ることread()は、実際に停止する合図です。これは、たとえば、停止するタイミングを urlretrieve が処理する方法です。TCP/IP とソケットは読み取りプロセスを抽象化し、相手側の接続が EOF で閉じられていない限り、追加データの待機をブロックします。この場合、接続からの read()ing は空の文字列を返します。空の文字列は、データの細流がないことを意味します...すべて処理されているため、順序付けられたパケットの再構成について心配する必要はありません。それが urllib2 の懸念事項である場合は、安全に使用できると思います。

于 2009-04-08T01:46:37.797 に答える