前言
先前有同事想要一個可以自由下載網站圖片的程式,因此我做了一個 chrome 擴充功能。這個擴充功能可以讓一鍵下載網站中的所有圖片,並且可以下載到你要的資料夾內,並且可以透過圖片的最小尺寸作為篩選。
在這篇文章中,我會介紹這個擴充功能的安裝方式、使用方式及程式碼。
安裝方式
因為目前這個程式還沒上到 google 的商店上面,因此要使用手動的安裝方式,以下將講解如何裝這個擴充功能。
未來如果有機會申請 google 商城上去,讓大家可以更方便的安裝。
下載文件
先下載下面的文件,並且解壓縮。
開啟擴充功能選單
點選 “擴充功能” > “管理擴充功能”
開啟開發人員選項
打開網頁右上方的"開發人員選項",並且會看到下面多一欄選項
載入未封裝項目
點選 “載入未封裝項目”,選擇剛剛下載後,解壓縮的資料夾。
安裝完成
安裝完成就會看到下面的這個擴充程式
使用方式
你可以在彈出視窗中輸入你想要的資料夾名稱,以及最小的圖片寬度(以像素為單位),這個是避免載到一些網站的 ICON,建議可以調到 600 px 以上,然後點擊下載按鈕,就可以開始下載圖片了。
然後從 chrome 預設下載的路徑中就可以看到剛剛下載的資料夾。
程式碼
圖片下載器的程式碼主要由以下幾個部分組成:
1 2 3 4 5 6 7 8 9 10
| |-- webImageDownloader |-- background.js |-- content.js |-- manifest.json |-- popup.html |-- popup.js |-- images |-- icon16.png |-- icon48.png |-- icon128.png
|
這個html,定義了擴充功能的彈出視窗的內容和樣式,包括一個文本框,一個數字框,和一個按鈕,用於讓用戶輸入資料夾名稱和最小的圖片寬度,然後下載圖片。這個檔案也引用了一個 popup.js ,用於處理用戶的操作和與其他部分溝通。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| <!doctype html> <html> <meta charset="utf-8"> <style>
html, body { width: 400px; height: 170px; overflow: auto; }
body { font-family: 'Arial', sans-serif; margin: 10px; background-color: #555; color: #aaa; }
input[type=text], input[type=number] { width: calc(100% - 22px); padding: 10px; margin-bottom: 10px; border: 1px solid #aaa; border-radius: 4px; box-sizing: border-box; background-color: #eee; }
button { width: calc(100% - 22px); padding: 10px; background-color: rgb(46, 69, 107); color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
button:hover { background-color: #194ca0; }
button:active { background-color: #1e3f86; }
#download { margin-top: 10px; }
</style>
<head><title>Image Downloader</title></head> <body> <input type="text" id="folderName" placeholder="Enter folder name"> <input type="number" id="minWidth" placeholder="Minimum image width (px)"> <button id="download">download Image</button> <script src="popup.js"></script> </body> </html>
|
manifest.json
這個 JSON 定義了擴充功能的基本資訊,如名稱,版本,權限,圖示,動作,背景服務,和內容腳本等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| { "manifest_version": 3, "name": "webImageDownloader", "version": "1.0", "permissions": ["activeTab", "downloads", "scripting"], "action": { "default_popup": "popup.html", "default_icon": { "16": "images/icon16.png", "48": "images/icon48.png", "128": "images/icon128.png" } }, "icons": { "16": "images/icon16.png", "48": "images/icon48.png", "128": "images/icon128.png" }, "background": { "service_worker": "background.js" }, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"] } ] }
|
content.js
這個 JavaScript 是擴充功能的內容腳本,它負責在每個網頁中執行一些操作,如監聽來自背景服務的訊息,並且根據用戶設定的最小尺寸,過濾和收集網頁中的圖片的網址,然後回傳給背景服務。
1 2 3 4 5 6 7 8 9 10
| chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === "extractImages") { const minSize = request.minSize; const images = Array.from(document.querySelectorAll('img')).filter(img => { return img.naturalWidth >= minSize && img.naturalHeight >= minSize; }).map(img => img.src); chrome.runtime.sendMessage({action: "downloadImages", images: images}); } });
|
這個 javaScript 是擴充功能的彈出視窗的邏輯,它負責監聽用戶的點擊事件,並且向背景服務或內容腳本發送訊息,請求執行下載圖片的動作。
1 2 3 4 5 6 7 8 9 10 11 12 13
| document.getElementById('download').addEventListener('click', () => { const folderName = document.getElementById('folderName').value; const minWidth = document.getElementById('minWidth').value; chrome.tabs.query({active: true, currentWindow: true}, (tabs) => { const activeTab = tabs[0]; chrome.runtime.sendMessage({ action: "downloadImages", tabId: activeTab.id, folderName: folderName, minWidth: minWidth }); }); });
|
background.js
這個 JavaScript 檔案,是擴充功能的背景服務,它負責在背景中執行一些持續性或事件驅動的任務,如監聽來自彈出視窗或內容腳本的訊息,並且調用 chrome API 來下載圖片,或者向內容腳本發送訊息,請求提取圖片的網址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| chrome.runtime.onInstalled.addListener(() => { console.log('Extension installed and running.'); });
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === "downloadImages") { chrome.scripting.executeScript({ target: { tabId: request.tabId }, function: findImages }, (results) => { for (const url of results[0].result) { chrome.downloads.download({ url: url }); } }); } });
function findImages(minWidth) { const images = document.querySelectorAll('img'); return Array.from(images) .filter(img => img.naturalWidth >= minWidth) .map(img => img.src); }
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === "downloadImages") { chrome.scripting.executeScript({ target: { tabId: request.tabId }, func: findImages, args: [parseInt(request.minWidth)] }, (results) => { if (results && results[0] && results[0].result) { for (const url of results[0].result) { chrome.downloads.download({ url: url, filename: request.folderName ? `${request.folderName}/${url.split('/').pop()}` : url.split('/').pop() }); } } }); } });
|