Instagram 保存ツール @neos21/igsv をより使いやすくするブックマークレット2つ
Instagram の画像・動画をダウンロードする、拙作の CLI ツール @neos21/igsv
。
npm 製なので、次のようにグローバルインストールすると、igsv
コマンドが使えるようになる。
$ npm install -g @neos21/igsv
コマンドの引数に Instagram の投稿ページの URL を指定すれば、カレントディレクトリ直下に ./igsv-downloads/
ディレクトリを作ってそこに画像や動画を保存する仕組み。
$ igsv https://www.instagram.com/p/XXXXXXXXXXX/
で、自分は Instagram の「保存」機能を使って保存したい画像を蓄えておき、コレを後で一括ダウンロードしている。その際使っているブックマークレット2つを紹介する。
目次
ブックマークレット集のサイトもドウゾ
今回紹介するブックマークレットを含め、コレまで作成してきたブックマークレットは以下の GitHub Pages で公開している。よかったらドウゾ。
Instagram の「保存済み」ページから URL をまとめて取得する
まずは Instagram の「保存済み」ページから URL をまとめて取得するブックマークレット。
javascript:((e,t,r,a)=>{r=setInterval(()=>{e.querySelectorAll("a").forEach(e=>{e.href.match(/(?!.*liked_by).*(?=\/p\/)/)&&t.add("igsv "+e.href+"\n")})},200),e.addEventListener("keydown",n=>{n.key.includes("Esc")&&(clearInterval(r),(a=e.createElement("textarea")).textContent=Array.from(t).join(""),e.body.appendChild(a),a.select(),e.execCommand("copy"),e.body.removeChild(a),alert(t.size+"件"))})})(document,new Set);
使い方
まず自分の Instagram の「保存済み」ページに移動する。/saved
な URL だ。
ココに行くと、自分が保存した投稿がズラッと並んでいると思うので、ブックマークレットを起動する。そしたらページをゆっくりスクロールしていき、「保存済み」の投稿のラストまでスクロールする。
スクロールが終わったら Esc
キーを押す。すると「○○件」というアラートダイアログが出ると思うので閉じる。この時、クリップボードには次のような igsv
コマンドがコピーされているはずだ。
igsv https://www.instagram.com/p/XXXXXXXXXXX/
igsv https://www.instagram.com/p/YYYYYYYYYYY/
igsv https://www.instagram.com/p/ZZZZZZZZZZZ/
ページをスクロールして表示した投稿の URL に igsv
コマンドを付与した文字列である。あとはコレをスクリプトファイルにでも保存して実行すれば、一括ダウンロードを簡単に始められる。
仕組み解説
基本的にやろうとしていることは、Instagram の「保存済み」ページにある a
要素を取得して、画像の投稿 URL を抽出しているだけだ。
しかし、「保存済み」ページは Virtual Scroll を導入していおり、初期表示時に全ての投稿 URL を引っこ抜けない (多くて21件分とかかな?)。
そこで、a
要素の内容を取得する処理を setInterval()
で回し続け、Esc
キーの押下をもってタイマーを止めるようにした。コレなら、バーチャルスクロールに応じて変化する a
要素の内容を全て引っこ抜けるだろう、というワケだ。手作業が発生するが仕方ないか…。
で、投稿 URL を保持するのに Set
を使った。Set は重複を許さない配列みたいなモノで、同じ値を set.add()
しても無視される。
コレを利用して、setInterval()
中の set.add()
は一律で投げ込むだけ投げ込んでいる。重複チェックとかしなくて良い。
Esc キーが押されたら、この Set
の内容をクリップボードにコピーして終了している。Esc キーの押下判定は keypress
だと難しいようなので、keydown
ないしは keyup
を使うと良い。
「保存」を一括解除する
次に、「保存」した投稿を削除するブックマークレット。自分はローカルに画像を保存できた投稿は「保存済み」から削除しているので、こうしたブックマークレットも作ってみた次第。
javascript:((e,r,t)=>{setInterval(()=>{(r=e.querySelector('svg[aria-label="削除する"]'))&&r.parentNode.click(),setTimeout(()=>{(t=e.querySelector("a.coreSpriteRightPaginationArrow"))&&t.click()},250)},3e3)})(document);
使い方
Instagram の「保存済み」ページに移動したら、1つ目の投稿を選択する。すると画面中央に投稿が表示され、右側に「>」アイコンが見えている画面になると思う。
この画面になったら準備完了。ブックマークレットを実行すれば、「保存済みを解除する」→「次の投稿に移動する」→「保存済を解除する」…という動きが自動的に行われる。よきところまで解除処理が進んだら、ページを再読み込みするなどしてブックマークレットを中断すれば良い。
仕組み解説
コチラも setInterval()
による繰返し処理。
各投稿にある「黒いしおり」のアイコン、保存済みにしたのを解除するアイコンだが、コイツは
document.querySelector('svg[aria-label="削除する"]')
で特定できる。この SVG 要素を囲んでいる一つ上の button
要素 (parentNode
) を click()
すれば、保存済みを解除できる。
そしたら次の投稿に移るため、「>」アイコンをクリックしたい。
- 次の投稿に進む「
>
」アイコンはdocument.querySelector('a.coreSpriteRightPaginationArrow')
- 前の投稿に戻る「
<
」アイコンはdocument.querySelector('a.coreSpriteLeftPaginationArrow')
で特定できるので、コレを押下すれば良い。
前後の投稿への移動は同じページ内で処理されるので、ブックマークレットによる setInterval()
が使えるというワケ。ただし非同期読み込みが発生するので、それを待つために3秒ほどの間隔を開けて繰返し処理をしている。ココらへんは回線速度によって調整する必要がある。
やろうと思えば、要素の存在チェックや描画更新を待機したりして処理を自動化することもできるが、自分はこの程度の雑なスクリプトで事足りているので、コレで良しとする。
以上。