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"]
}]
}
上記の設定により、httpとhttpsプロトコルのすべてのページでutils.jsとcollector.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との通信設計、ダウンロード連携処理など、実用的な機能拡張も視野に入れて進めていきます。