0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

開いている全タブの情報をテキストに集約するChrome拡張を自作する

Posted at

概要

 開いている全タブの内容を一つのテキストの集約して生成AIに渡したい。
 前回はデバッグ機能とPythonで実現したが、テキスト化までの操作が多く面倒だった。

 今回はChrome拡張として作成し、対象のウィンドウで操作するだけで取得できるようにする。
 既にそういう拡張があると思われるが、自作すればコードがわかっていて安全だし、Chrome拡張を作る勉強になる。
 この記事では拡張機能作成から読み込みまでの流れを解説する。

今回のコードでできること

Chromeで複数のタブを開いている状態で今回の拡張を実行すると
image.png
image.png
image.png

mdファイルがダウンロードされ、
image.png

Chromeの全タブのURL一覧とそのURLの内容がひとつのテキストにまとまっている。
image.png

拡張機能作成

フォルダ構成に合わせて各ファイルを用意する。

フォルダ構成

tab-to-markdown-extension/
├─ manifest.json
├─ popup.html
├─ popup.js
├─ content.js
└─ readability.js

manifest.json

{
  "manifest_version": 3,
  "name": "Tab to Markdown Exporter",
  "version": "1.0",
  "description": "Open tabs → extract content → export Markdown",
  "permissions": [
    "tabs",
    "scripting",
    "downloads"
  ],
  "host_permissions": [
    "<all_urls>"
  ],
  "action": {
    "default_popup": "popup.html"
  }
}

popup.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <style>
    body {
      width: 240px;
      font-family: sans-serif;
    }
    button {
      width: 100%;
      padding: 10px;
      font-size: 14px;
    }
  </style>
</head>
<body>
  <button id="export">Export Tabs to Markdown</button>
  <script src="popup.js"></script>
</body>
</html>

popup.js

document.getElementById("export").onclick = async () => {
  const tabs = await chrome.tabs.query({ currentWindow: true });

  let md = "# Open Chrome Tabs (Markdown Converted)\n\n";

  // =========================
  // URL List
  // =========================
  md += "## URL List\n\n";
  tabs.forEach((tab, i) => {
    md += `${i + 1}. [${tab.title || "No Title"}](${tab.url})  \n`;
  });

  md += "\n\n---\n";

  // =========================
  // 各タブ本文取得
  // =========================
  for (let i = 0; i < tabs.length; i++) {
    const tab = tabs[i];

    if (!tab.url || !tab.url.startsWith("http")) continue;

    try {
      const [{ result }] = await chrome.scripting.executeScript({
        target: { tabId: tab.id },
        files: ["readability.js", "content.js"]
      });

      md += `\n\n---\n`;
      md += `## ${i + 1}. ${result.title}\n`;
      md += `- URL: ${tab.url}\n\n`;
      md += `### ▼ Markdown Content\n\n`;
      md += result.markdown + "\n";

    } catch (e) {
      md += `\n\n---\n`;
      md += `## ${i + 1}. ${tab.title}\n`;
      md += `- URL: ${tab.url}\n\n`;
      md += `**[ERROR]** ${e}\n`;
    }
  }

  downloadMarkdown(md);
};

function downloadMarkdown(text) {
  const blob = new Blob([text], { type: "text/markdown" });
  const url = URL.createObjectURL(blob);

  chrome.downloads.download({
    url,
    filename: "tabs_output.md",
    saveAs: true
  });
}

content.js

(() => {
  const article = new Readability(document.cloneNode(true)).parse();

  if (!article) {
    return {
      title: document.title,
      markdown: "_本文を抽出できませんでした_"
    };
  }

  const text = article.textContent
    .split("\n")
    .map(l => l.trim())
    .filter(l => l.length > 0)
    .join("\n\n");

  return {
    title: article.title || document.title,
    markdown: text
  };
})();

readability.js

 以下のGithubを保存する。

 以下のコマンドをコマンドプロンプトで実行すれば取得できる。

curl -O https://raw.githubusercontent.com/mozilla/readability/main/Readability.js
rename Readability.js readability.js

拡張機能読み込み

① chromeで拡張機能の画面に移動。以下のURLでも飛べる。

chrome://extensions/

② デベロッパーモードをON。
image.png

③ 「パッケージ化されていない拡張機能を読み込む」を選択。

image.png

④ 今回作成したフォルダ「tab-to-markdown-extension」を選択。

これで自作した拡張が追加される。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?