自動化厨のプログラミングメモブログ │ CODE:LIFE

Python/VBA/GAS/JavaScript/Raspberry Piなどで色んなことを自動化

【コピペでOK】PDFファイル一括ダウンロード。ブラウザで開かずにダウンロードさせる方法

この記事でできるようになること

  • Webページ内のすべてのPDFリンクを一括ダウンロードできるようになる
  • ブラウザでPDFファイルを開かずに直接ダウンロードさせる設定ができるようになる
  • JavaScriptを使ってaタグにdownload属性を付与する方法を理解できる
  • ブラウザの「名前をつけて保存」ダイアログを省略する設定ができるようになる
  • URLからファイル名を抽出する方法を学べる

※複数ページを横断して実行する場合は以下記事を参考にサブウィンドウを活用してみてください

codelife.cafe


サンプルコード: ページ内のすべてのPDFリンクにdownload属性付与して開く

F12でブラウザコンソールを開いてコピペで動きます

// ファイル名取得関数
const getFilename = url => new URL(url).pathname.split('/').pop();

// スリープ関数
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

// PDFファイルのaタグにdownload属性を付与
const links = [...document.querySelectorAll("a")]
    .filter(a => /\.pdf/.test(a.href))
    .map(a => {
        const fileName = getFilename(a.href);
        a.setAttribute("download", fileName);
        a.setAttribute("target", "_blank");
        return a;
    });

// 全てのリンクを順番にクリック
for (const link of links){
    await sleep(1000);
    console.log(link.href);
    link.click();
}

ダウンロードされずブラウザで開かれてしまう場合

ブラウザの設定で「PDF」を検索、デフォルトの動作が「Chrome で PDF を開く」担っている場合は「PDF をダウンロードする」に変更する。

名前をつけて保存のウィンドウが表示されてしまい停止する場合

ブラウザ設定「ダウンロード」を確認。「ダウンロード前に各ファイルの保存場所を確認する」がONになっている場合はOFFに変更することで名前をつけて保存のステップを省略できる。

解説

download属性とは

aタグに download 属性を設定するとファイルを開くのではなくファイルの保存となる。

同一オリジンの URL と、 blob:、 data: の各スキームでのみ動作する

※download属性が無い場合はレスポンスヘッダー Content-Disposition によって判定される

<a href="https://codelife.cafe/file.pdf" download="file.pdf">

値の部分はダウンロード時のデフォルトファイル名に用いられる。

ファイル名をどのように取得・セットするか

サンプルコードではURLからファイル名部分を取り出す関数を使用することで正しいファイル名で保存させるように書いてあります。

// URLからファイル名だけ取り出す関数
const getFilename = url => new URL(url).pathname.split('/').pop();

URL クラスの pathname はhttps~ドメインと ? 以降のパラメータ部分を除去して /path/to/file.pdf の部分だけを取り出してくれます。

それを .split('/') でスラッシュごとに配列に分割し、 .pop() で一番最後の要素を取り出すことでファイル名部分だけを抽出しています。

// パラメーターがない場合
getFilename('https://example.com/path/to/file.pdf'); 
// => "file.pdf"

// パラメーターがある場合
getFilename('https://example.com/path/to/image.jpg?v=123'); 
// => "image.jpg"

// スラッシュで終わるURLの場合
getFilename('https://example.com/path/to/directory/'); 
// => ""

target属性に _blank を設定する理由

aタグに target 属性を設定するとリンクをどのタブ、ウィンドウで開くか指定できる。

_blank を指定することでページ遷移によるスクリプト中断を抑制する。

<a href="https://codelife.cafe/file.pdf" target="_blank">
動作
_blank 新しいタブ・ウィンドウで開く
_self 現在のタブ・ウィンドウで開く
_top iframeを無視して現在のタブ・ウィンドウで開く
_parent iframe内の場合は親フレーム(フレームではない場合タブ・ウィンドウ)で開く