最近Pythonに手を出し始めました。
今回気になったのは次のこと
- URLからファイルサイズを調べたい
- ただしダウンロード無しで
通信にはrequestsを使っていました。
それを使うこと前提の方法です
ヘッダー取得してrequestsからDLなしでサイズ取得
まずURLからヘッダーだけ取得します。
▼ requests.head().headersについて
PUT、DELETE、HEAD、OPTIONSなどの他のHTTPリクエストについても本当にとてもシンプルです。:
>>> r = requests.put("http://httpbin.org/put")
>>> r = requests.delete("http://httpbin.org/delete")
>>> r = requests.head("http://httpbin.org/get")
>>> r = requests.options("http://httpbin.org/get")Pythonの辞書形式で簡単にサーバーのレスポンスヘッダーを見ることができます。:
> r.headers
{
'status': '200 OK',
'content-encoding': 'gzip',
'transfer-encoding': 'chunked',
'connection': 'close',
'server': 'nginx/1.0.4',
'x-runtime': '148ms',
'etag': '"e1ca502697e5c9317743dc078f67693f"',
'content-type': 'application/json; charset=utf-8'
}
辞書とはいえ、特別です。辞書はHTTPヘッダーを作成するためだけに作られます。 RFC 2616 によると、HTTPヘッダーは大文字と小文字を区別しません。引用元 : https://requests-docs-ja.readthedocs.io/en/latest/user/quickstart/
ヘッダーだけ取得するのに requests.head() が用意されており、そこから headers を参照すると content-length というキーも含まれてます。そこからファイルサイズ取得可能です
具体的には次のようなコードですね
▼ URLからファイルサイズ取得
1 2 3 4 5 6 |
url = 'https://hoge.com/video.mp4' response = requests.head(url, allow_redirects=True) size = response.headers.get('content-length', -1) print('size : '+str(size)+' bytes') ## => size : 182645 bytes |
ハイ、このように取得できました。
分かりやすく関数化しておく
こういう風に関数化しておきます
1 2 3 4 5 6 7 |
def len_from_url(url): url = 'https://hoge.com/video.mp4' r = requests.head(url, allow_redirects=True) if(r.status_code == 200): return r.headers.get('content-length', -1) else: return -1 |
さっきは書かなかったけど r.status_code でステータスコードを調べ、正常ならファイルサイズ取得・それ以外では一応 -1 を返す仕様にしました
MB・GBなどの単位付きでファイルサイズ取得してみる
ここからは蛇足ですが…
ファイルサイズを単位付きで表示してみます
▼ こういう関数を用意する
1 2 3 4 5 6 7 8 9 |
def convert_size(size_bytes): size_bytes = float(size_bytes) if size_bytes == 0: return "0B" size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") i = int(math.floor(math.log(size_bytes, 1024))) p = math.pow(1024, i) s = round(size_bytes / p, 2) return "%s %s" % (s, size_name[i]) |
▼ 単位付きでファイルサイズ表示
1 2 3 4 5 6 7 8 9 10 11 |
url = 'https://hoge.com/video.mp4' r = requests.head(url, allow_redirects=True) if(r.status_code == 200): size = convert_size( r.headers.get('content-length', -1) ) else: size = '' print('size : '+size) /// => size : 18.3MB |
なんかの役に立つはずなので残しておきます
URLからファイルサイズ取得は意外と簡単
ここまで書いたように…
- requestsからヘッダーだけ取得
- その中のcontent-lengthを参照
- それがバイト数でのファイルサイズ
以上、PythonでDLなしでファイルサイズを調べる方法でした。
もしもっと最良の方法があれば教えてください。ではまた