Python
 Computer >> コンピューター >  >> プログラミング >> Python

PythonでWebからファイルをダウンロードする方法|requestsライブラリの使い方を徹底解説

Pythonには、urllibやrequestsなど、Webからファイルをダウンロードするためのさまざまなモジュールが用意されています。本記事では、その中でも定番のrequestsライブラリを使用して、URLから効率的にファイルをダウンロードする方法を、ステップごとにわかりやすく解説します。

requestsライブラリでファイルをダウンロードする基本手順

1. モジュールをインポートする

import requests

2. ダウンロード対象のURLを指定する

url = 'https://www.facebook.com/favicon.ico'
r = requests.get(url, allow_redirects=True)

allow_redirects=True を指定することで、リダイレクトが発生した場合でも自動的に追跡してくれます。

3. ファイル名を付けてコンテンツを保存する

open('facebook.ico', 'wb').write(r.content)

ここでは、バイナリ書き込みモード('wb')でファイルを開き、レスポンスの内容を「facebook.ico」という名前で保存しています。

完全なサンプルコード

import requests

url = 'https://www.facebook.com/favicon.ico'
r = requests.get(url, allow_redirects=True)

open('facebook.ico', 'wb').write(r.content)

実行結果

PythonでWebからファイルをダウンロードする方法|requestsライブラリの使い方を徹底解説

スクリプトを実行すると、カレントワーキングディレクトリにアイコンファイルがダウンロードされていることが確認できます。

ダウンロード可能なファイルかどうかを判定する

実際には、画像・テキスト・動画など、さまざまな種類のファイルをWebからダウンロードする必要があります。まずは、URLがどのような種類のデータにリンクしているのかを確認してみましょう。

>>> r = requests.get(url, allow_redirects=True)
>>> print(r.headers.get('content-type'))
image/png

ただし、もっと賢い方法があります。それは、実際にダウンロードを行う前に、URLのヘッダー情報だけを先に取得しておくというものです。これにより、ダウンロードを意図していないページなどを事前にスキップできます。

>>> print(is_downloadable('https://www.youtube.com/watch?v=xCglV_dqFGI'))
False
>>> print(is_downloadable('https://www.facebook.com/favicon.ico'))
True

ファイルサイズによるダウンロード制限

ファイルサイズでダウンロードを制限したい場合は、content-lengthヘッダーからファイルサイズを取得し、要件に応じて処理を分岐させることができます。

contentLength = header.get('content-length', None)
if contentLength and contentLength > 2e8: # 約200MB
    return False

URLからファイル名を取得する

ファイル名を取得するには、URLを解析します。以下は、スラッシュ(/)以降の最後の文字列を取り出すサンプルコードです。

url = "https://www.computersolution.tech/wp-content/uploads/2016/05/tutorialspoint-logo.png"
if url.find('/'):
    print(url.rsplit('/', 1)[1])

上記のコードでURLからファイル名を取得できます。しかし、「https://url.com/download」のように、URL自体にファイル名の情報が含まれていないケースも少なくありません。そのような場合は、ファイル名情報を含むContent-Dispositionヘッダーを取得する必要があります。

Content-Dispositionヘッダーからファイル名を取得する

import requests
import re

def getFilename_fromCd(cd):
    """
    Content-Dispositionからファイル名を取得する
    """
    if not cd:
        return None
    fname = re.findall('filename=(.+)', cd)
    if len(fname) == 0:
        return None
    return fname[0]

url = 'https://google.com/favicon.ico'
r = requests.get(url, allow_redirects=True)
filename = getFilename_fromCd(r.headers.get('content-disposition'))
open(filename, 'wb').write(r.content)

上記のURL解析コードとこのプログラムを組み合わせれば、ほとんどの場合、Content-Dispositionヘッダーから正しくファイル名を取得できるようになります。

まとめ

Pythonのrequestsライブラリを使えば、わずか数行のコードでWeb上のファイルを簡単にダウンロードできます。押さえておきたいポイントは以下の通りです。

  • 基本的なダウンロード: requests.get()でレスポンスを取得し、r.contentをバイナリモードで保存する
  • ダウンロード可否の判定: ヘッダーのcontent-typeを事前に確認すれば、不要なダウンロードを回避できる
  • サイズ制限: content-lengthヘッダーをチェックして、大きすぎるファイルのダウンロードを防止できる
  • ファイル名の取得: URLの解析に加えてContent-Dispositionヘッダーも活用すると、より確実にファイル名を特定できる
  1. PythonのlxmlでWebスクレイピングを実装する方法|Yahoo Financeから株価データを抽出

    Webスクレイピングは、データサイエンス愛好家だけでなく、Webサイトの仕組みを深く掘り下げたい学生や学習者にとっても非常に魅力的な技術です。Pythonには強力なスクレイピングライブラリが数多く用意されています。 Scrapy Urllib BeautifulSoup Selenium Requests lxml 本記事では、その中でもlxmlライブラリを使ってWebページからデータを抽出する方法を解説します。lxmlはC言語製のXML解析ライブラリ「libxml2」をベースに構築されており、Beautiful Soupよりも高速に動作するのが大きな魅力です。一方で、特にWindows環

  2. Pythonで複数のファイル名を一括変更する方法【os.rename()活用】

    Python3では、rename()メソッドを使うことで、ファイルやディレクトリの名前を簡単に変更できます。このメソッドは標準ライブラリのosモジュールに含まれており、追加のインストールなしですぐに利用可能です。 os.rename() の基本構文 os.rename(src, dst) 各引数の意味は以下のとおりです。 src: 名前を変更したい元のファイル(またはディレクトリ)のパス dst: 変更後の新しい名前を含むパス それでは、複数の画像ファイルが入ったフォルダを例に、一括でファイル名を変更する方法を見ていきましょう。ここでは、次のような画像フォルダを使用します。 入力(変更前の