ブックマークレット・コンソールを使って Webページ内の複数の指定要素のテキストをファイルに保存

タイトルの通りの内容を、自分用のメモとして。

頻度は多くないものの、とある Webサイト上に登録された情報をまとめる作業があり、CSV出力する機能がありはするのですが、より手軽に情報をまとめられないかと思ってやってみた内容です。

## 開発者ツールのコンソールで処理を実行
とりあえず、以下を実行する処理について調べたり試してみたりしました。

- ページ内の指定要素を取得する処理
- 取得したテキストをファイルとして保存する処理

### ページ内の指定要素のテキストを取得してまとめる
処理対象として、Qiita のトップページを使ってみます。
適当に決めた内容ですが、「トップページでトレンドとして表示されている記事のタイトルをまとめて取得する」ということをやってみます。

開発者ツールで該当する部分の構成を見てみます。

![Qiitaのトップページ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/f3dafc6f-8d47-afaa-8364-c0c82bc0abec.jpeg)

article の子要素の h2 が記事のタイトルのようです。試しに、ページ内のこれらを取得する処理を、コンソールで実行してみます。

```javascript
const el = document.querySelectorAll("article h2");
```

コンソール上で取得した中身の情報を見てみると、うまく取得できていそうです。

![取得した要素.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/003bcba9-5be6-b4b0-476f-0ef2e32fd4e7.jpeg)

![取得した要素のうちの1つ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/7c9c4f00-9fcc-124a-e0e1-22ac5af4dce1.jpeg)

上記の `el` は [NodeList](https://developer.mozilla.org/ja/docs/Web/API/NodeList) になっているようで、取得した内容をひとまとめにするには配列にしておくのが良さそうです。さらに、テキストの部分を取り出すようにしてみます。

```javascript
const array = Array.from(el).map(val => val.textContent);
```

この処理で配列に変換しつつ、テキストの部分のみを取り出せました。

![配列に変換.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/c5762ace-4209-5707-7fea-6a11d0769ec3.jpeg)

そして、ひとまとまりの内容にするために、配列の各要素を改行文字をはさみつつ、連結させてみます。

```javascript
const text = array.join('\n');
```

出力した内容は、こんな感じになりました。
![タイトルをひとまとめに.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/0f5af546-fd16-09df-8300-260bdd46c6c7.jpeg)

### スプレッド構文を使ったやり方
ちなみに、`Array.from()` を使った部分はスプレッド構文を使う形でも大丈夫です。具体的には、以下となります。

```javascript
const text = [...el].map(val => val.textContent).join('\n');
```

### テキストをファイルに保存する
テキストの内容を何らか出力してコピペする方法も考えたのですが、調べてみるとファイルで保存する方法があるようでした。以下の処理を実行すると、「【保存するテキスト】」というテキストが書かれたファイルが生成され、さらにそのファイルのダウンロードが自動的に始まります。

```javascript
const blob = new Blob(["【保存するテキスト】"],{type:"text/plan"});
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = '出力するテキストのファイル名.txt';
link.click();
```
## 2つの処理をまとめる
上記の 2つの処理をまとめたものが以下となります。

```javascript
const el = document.querySelectorAll("article h2");
const array = Array.from(el).map(val => val.textContent);
const text = array.join('\n');

const blob = new Blob([text],{type:"text/plan"});
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = '出力するテキストのファイル名.txt';
link.click();
```

Qiita のトップページを開き、開発ツールのコンソールで上記を実行すると、テキストファイルが保存されます。そのテキストファイルの中には、トップページに表示されていた記事のタイトルが 1行に 1つずつ書かれています。

## ブックマークレット用に変換する
ブックマークレットについて調べていると、以下のページの情報を見かけました。

●Bookmarkletを作ろう(準備編） - Qiita
　https://qiita.com/kanaxx/items/63debe502aacd73c3cb8

Googleさんの [Closure Compiler](https://closure-compiler.appspot.com/home) を使うのが良いらしいです。また、上記の内容を見て、`javascript: (function () { 【処理の内容】 })();` という形になるようにしました。

```javascript
javascript: (function () {
  const el = document.querySelectorAll("article h2");
  const array = Array.from(el).map((val) => val.textContent);
  const text = array.join("\n");

  const blob = new Blob([text], { type: "text/plan" });
  const link = document.createElement("a");
  link.href = URL.createObjectURL(blob);
  link.download = "出力するテキストのファイル名.txt";
  link.click();
})();
```

そして、Closure Compiler で上記を処理した結果は、以下のようになりました。

```javascript
(function(){var a=document.querySelectorAll("article h2");a=Array.from(a).map(function(c){return c.textContent}).join("\n");a=new Blob([a],{type:"text/plan"});var b=document.createElement("a");b.href=URL.createObjectURL(a);b.download="\u4f5c\u3063\u305f\u30d5\u30a1\u30a4\u30eb.txt";b.click()})();
```

この先頭に再度 `javascript:`をつけた以下の内容にして、ブックマークの URL欄に設定してやることで、ブックマークから処理を実行できるようになりました。

```javascript
javascript:(function(){var a=document.querySelectorAll("article h2");a=Array.from(a).map(function(c){return c.textContent}).join("\n");a=new Blob([a],{type:"text/plan"});var b=document.createElement("a");b.href=URL.createObjectURL(a);b.download="\u4f5c\u3063\u305f\u30d5\u30a1\u30a4\u30eb.txt";b.click()})();
```

今回の内容は以上になります。

## 参照したサイト

●[JavaScript] nodeListから配列に変更する方法 - Qiita
　https://qiita.com/kibinag0/items/faaf684fbd366ec3cc66

●JavaScriptのarrayのmap関数でアロー関数を使う - Qiita
　https://qiita.com/kanta13jp1/items/e79eb64c27db2d7d9620

●スプレッド構文 - JavaScript | MDN
　https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax

●【JavaScript】スプレッド構文の便利な使い方まとめ - Qiita
　https://qiita.com/Nossa/items/e6f503cbb95c8e6967f8