Python 3でWebからファイルをダウンロードする 質問する

Python 3でWebからファイルをダウンロードする 質問する

私は、同じゲーム/アプリケーションの .jad ファイルで指定された URL を読み取って、Web サーバーから .jar (java) ファイルをダウンロードするプログラムを作成しています。Python 3.2.1 を使用しています。

JAD ファイルから JAR ファイルの URL を抽出することができました (すべての JAD ファイルには JAR ファイルへの URL が含まれています)。ただし、ご想像のとおり、抽出された値は type() 文字列です。

関連する関数は次のとおりです。

def downloadFile(URL=None):
    import httplib2
    h = httplib2.Http(".cache")
    resp, content = h.request(URL, "GET")
    return content

downloadFile(URL_from_file)

しかし、上記の関数の型は文字列ではなくバイトでなければならないというエラーが常に発生します。URL.encode('utf-8') と bytes(URL,encoding='utf-8') の使用も試みましたが、常に同じまたは類似のエラーが発生します。

つまり、私の質問は、URL が文字列型で保存されている場合に、サーバーからファイルをダウンロードするにはどうすればよいかということです。

ベストアンサー1

ウェブページの内容を変数に取得したい場合はreadurllib.request.urlopen:

import urllib.request
...
url = 'http://example.com/'
response = urllib.request.urlopen(url)
data = response.read()      # a `bytes` object
text = data.decode('utf-8') # a `str`; this step can't be used if data is binary

ファイルをダウンロードして保存する最も簡単な方法は、urllib.request.urlretrieve関数:

import urllib.request
...
# Download the file from `url` and save it locally under `file_name`:
urllib.request.urlretrieve(url, file_name)
import urllib.request
...
# Download the file from `url`, save it in a temporary directory and get the
# path to it (e.g. '/tmp/tmpb48zma.txt') in the `file_name` variable:
file_name, headers = urllib.request.urlretrieve(url)

urlretrieveしかし、考慮されることを忘れないでください遺産廃止される可能性があります (理由は不明ですが)。

最も正しい方法は、urllib.request.urlopenHTTPレスポンスを表すファイルのようなオブジェクトを返し、それを実際のファイルにコピーする関数shutil.copyfileobj

import urllib.request
import shutil
...
# Download the file from `url` and save it locally under `file_name`:
with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
    shutil.copyfileobj(response, out_file)

これが複雑すぎると思われる場合は、もっと単純にして、ダウンロード全体をオブジェクトに保存しbytes、それをファイルに書き込むこともできます。ただし、これは小さなファイルの場合にのみ有効です。

import urllib.request
...
# Download the file from `url` and save it locally under `file_name`:
with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
    data = response.read() # a `bytes` object
    out_file.write(data)

圧縮されたデータをその場で抽出(およびおそらく他の形式)することも可能です.gzが、そのような操作では、HTTP サーバーがファイルへのランダム アクセスをサポートしている必要がある可能性があります。

import urllib.request
import gzip
...
# Read the first 64 bytes of the file inside the .gz archive located at `url`
url = 'http://example.com/something.gz'
with urllib.request.urlopen(url) as response:
    with gzip.GzipFile(fileobj=response) as uncompressed:
        file_header = uncompressed.read(64) # a `bytes` object
        # Or do anything shown above using `uncompressed` instead of `response`.

おすすめ記事