Chrome拡張機能のContent Scriptを活用した画像収集機構

Chrome拡張機能の開発において、page内に содержимое を注入し動的に情報を取得・加工するための仕組みとしてcontent scriptが存在します。ここでは、 Webページ上に存在する画像リソースを多様な手段で動的に収集する実装を解説します。

内容として、以下の情報を収集する機能を実現します:

  • <img>要素のsrc属性値
  • CSSのbackground-imageで指定された画像URL
  • ユーザーが定義した任意属性から取得するリンク値(例:data-srcなど)

manifest.jsonとContent Scriptのセットアップ

拡張機能の基本設定はmanifest.jsonで行います。この拡張ではpopupページとcontent scriptを組み合わせて動作させます。content scriptの登録に関する設定は以下の通りです:

{
  "manifest_version": 2,
  "name": "Image Extractor",
  "description": "Webページ上の画像を多角的に収集・提供するツール",
  "version": "1.0",
  "browser_action": {
    "default_icon": "icon16.png",
    "default_popup": "/popup/popup.html"
  },
  "permissions": ["tabs", "downloads"],
  "icons": {
    "16": "icon16.png",
    "48": "icon48.png",
    "128": "icon128.png"
  },
  "content_scripts": [{
    "matches": ["http://*/*", "https://*/*"],
    "js": ["utils.js", "collector.js"]
  }]
}

上記の設定により、httphttpsプロトコルのすべてのページでutils.jscollector.jsが画面読み込み時に注入されます。

共通ユーティリティ関数(utils.js)

画像URLの正規化とエラーログ出力用の汎用手段を提供するユーティリティモジュールです。

// 相対パスやprotocol-relative URLを絶対URLへ変換
const normalizeUrl = (fragment, origin) => {
    if (!fragment) return '';
    const trimmed = fragment.trim();
    if (trimmed.startsWith('//')) {
        return `http:${trimmed}`;
    }
    if (trimmed.startsWith('/')) {
        const base = origin.endsWith('/') ? origin : origin + '/';
        return origin + trimmed.slice(1);
    }
    return trimmed;
};

// デバッグ出力:現時刻+メッセージをconsoleログへ記録
const logDebug = (message) => {
    const timestamp = new Date().toLocaleString();
    console.log(`[${timestamp}] ${message}`);
};

変換ロジックでは、特にCDN用パスや相対パスを処理できるように設計しており、後続の画像収集処理で正確なURLを保証します。

画像収集器(collector.js)

本体の収集ロジックはcollector.jsに実装されています。各コレクタは button クリックなどのイベント契機で起動し、結果として配列を返すようにします。 以下の3種類の画像取得函(function)を用意します。

1. <img>要素のsrc収集

const extractImageSources = () => {
    const candidates = Array.from(documentgetElementsByTagName('img'));
    const list = [];
    candidates.forEach(img => {
        const normalized = normalizeUrl(img.src, window.location.origin);
        if (normalized) list.push(normalized);
    });
    return list;
};

document.querySelectorAll('img')で要素を取得し、src属性を正規化した上で一覧化します。

2. background-imageのURL取得

const extractBackgroundImages = () => {
    const allElements = document.querySelectorAll('*');
    const result = [];
    allElements.forEach(node => {
        const style = window.getComputedStyle(node);
        const bgUrl = style.backgroundImage;
        const match = bgUrl.match(/url\(['"]?([^'")]+)['"]?\)/);
        if (match && match[1]) {
            const normalized = normalizeUrl(match[1], window.location.origin);
            if (normalized) result.push(normalized);
        }
    });
    return result;
};

getComputedStyleを活用して各DOMのbackground-imageプロパティを取得。正規表現でurl(...)部分を抽出し、URLとして正規化します。 ※複数background-imageが存在する場合、最初の1つだけを対象とします。

3. 任意属性値の収集(カスタムルール対応)

const configurableAttributes = ['data-src', 'data-lazy', 'data-srcset'];
const extractCustomAttrValues = () => {
    let values = [];
    configurableAttributes.forEach(attr => {
        const nodes = document.querySelectorAll(`[${attr}]`);
        nodes.forEach(el => {
            const raw = el.getAttribute(attr);
            const normalized = normalizeUrl(raw, window.location.origin);
            if (normalized) values.push(normalized);
        });
    });
    return values;
};

configurableAttributesに列挙した属性名を対象に、DOM上の該当属性を全検索します。独自画像遅延読み込み実装など、data-src系の属性に画像URLを格納するケースに対応可能です。

実行トリガと外出し

上述の3つの関数は、拡張機能のボタン押下時にpopup画面からchrome.runtime.sendMessageでexecuteし、content script側のchrome.runtime.onMessage.addListenerで受け取り、実行結果をJSON形式で返却します。 Declareした関数群はreturnsで結果を返すのみで、副作用(DOM書き換えなど)は行わず、結果加工処理はpopup側で統一して行う設計とします。

今後はpopupとの通信設計、ダウンロード連携処理など、実用的な機能拡張も視野に入れて進めていきます。

タグ: ChromeExtension ContentScript BackgroundImage image-extraction DOM-analysis

8月19日 00:49 投稿