deepseek v3-0324实现浏览器插件:图片抓取与下载工具

发布于:2025-04-02 ⋅ 阅读:(13) ⋅ 点赞:(0)

浏览器插件:图片抓取与下载工具

下面是一个完整的浏览器插件代码,可以抓取当前页面的所有图片,提供预览功能,并允许用户选择下载。

文件结构

image-downloader/
├── manifest.json
├── popup.html
├── popup.js
├── popup.css
└── icons/
    ├── icon48.png
    └── icon128.png

1. manifest.json

{
  "manifest_version": 3,
  "name": "图片抓取与下载工具",
  "version": "1.0",
  "description": "抓取当前页面的所有图片并提供下载功能",
  "permissions": ["activeTab", "downloads"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "icons": {
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  }
}

2. popup.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>图片抓取工具</title>
  <link rel="stylesheet" href="popup.css">
</head>
<body>
  <div class="container">
    <h1>页面图片抓取</h1>
    <div class="controls">
      <button id="fetchImages">抓取图片</button>
      <button id="downloadSelected">下载选中图片</button>
      <button id="selectAll">全选</button>
      <button id="deselectAll">取消全选</button>
    </div>
    <div class="filter">
      <label for="minWidth">最小宽度:</label>
      <input type="number" id="minWidth" placeholder="最小宽度" min="0">
      <label for="minHeight">最小高度:</label>
      <input type="number" id="minHeight" placeholder="最小高度" min="0">
    </div>
    <div id="status"></div>
    <div id="imageGallery"></div>
  </div>
  <script src="popup.js"></script>
</body>
</html>

3. popup.css

body {
  width: 600px;
  padding: 10px;
  font-family: Arial, sans-serif;
}

.container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

h1 {
  font-size: 18px;
  margin: 0 0 10px 0;
  text-align: center;
}

.controls {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
}

button {
  padding: 5px 10px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #45a049;
}

.filter {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

.filter input {
  width: 60px;
  padding: 3px;
}

#status {
  color: #666;
  font-style: italic;
  min-height: 20px;
}

#imageGallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
  max-height: 500px;
  overflow-y: auto;
  margin-top: 10px;
}

.image-container {
  border: 1px solid #ddd;
  padding: 5px;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.image-container img {
  max-width: 100%;
  max-height: 100px;
  object-fit: contain;
  margin-bottom: 5px;
}

.image-info {
  font-size: 12px;
  text-align: center;
  word-break: break-all;
}

.checkbox-container {
  margin-top: 5px;
}

4. popup.js

document.addEventListener('DOMContentLoaded', function() {
  const fetchImagesBtn = document.getElementById('fetchImages');
  const downloadSelectedBtn = document.getElementById('downloadSelected');
  const selectAllBtn = document.getElementById('selectAll');
  const deselectAllBtn = document.getElementById('deselectAll');
  const minWidthInput = document.getElementById('minWidth');
  const minHeightInput = document.getElementById('minHeight');
  const imageGallery = document.getElementById('imageGallery');
  const statusDiv = document.getElementById('status');

  let currentImages = [];

  // 抓取页面图片
  fetchImagesBtn.addEventListener('click', async function() {
    statusDiv.textContent = '正在抓取图片...';
    
    try {
      const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
      
      // 注入内容脚本获取图片
      const results = await chrome.scripting.executeScript({
        target: {tabId: tab.id},
        func: getPageImages,
      });
      
      if (results && results[0] && results[0].result) {
        currentImages = results[0].result;
        filterAndDisplayImages();
        statusDiv.textContent = `找到 ${currentImages.length} 张图片`;
      } else {
        statusDiv.textContent = '未找到图片或发生错误';
      }
    } catch (error) {
      console.error('抓取图片时出错:', error);
      statusDiv.textContent = '抓取图片时出错: ' + error.message;
    }
  });

  // 下载选中的图片
  downloadSelectedBtn.addEventListener('click', function() {
    const selectedImages = currentImages.filter(img => img.selected);
    
    if (selectedImages.length === 0) {
      statusDiv.textContent = '请先选择要下载的图片';
      return;
    }
    
    statusDiv.textContent = `正在下载 ${selectedImages.length} 张图片...`;
    
    selectedImages.forEach(img => {
      chrome.downloads.download({
        url: img.src,
        filename: getFilenameFromUrl(img.src),
        conflictAction: 'uniquify'
      });
    });
    
    statusDiv.textContent = `已开始下载 ${selectedImages.length} 张图片`;
  });

  // 全选
  selectAllBtn.addEventListener('click', function() {
    currentImages.forEach(img => img.selected = true);
    renderImages();
  });

  // 取消全选
  deselectAllBtn.addEventListener('click', function() {
    currentImages.forEach(img => img.selected = false);
    renderImages();
  });

  // 过滤条件变化时重新显示图片
  minWidthInput.addEventListener('change', filterAndDisplayImages);
  minHeightInput.addEventListener('change', filterAndDisplayImages);

  // 根据过滤条件筛选并显示图片
  function filterAndDisplayImages() {
    const minWidth = parseInt(minWidthInput.value) || 0;
    const minHeight = parseInt(minHeightInput.value) || 0;
    
    const filteredImages = currentImages.filter(img => {
      return img.naturalWidth >= minWidth && img.naturalHeight >= minHeight;
    });
    
    renderImages(filteredImages);
  }

  // 渲染图片到画廊
  function renderImages(imagesToRender = currentImages) {
    imageGallery.innerHTML = '';
    
    imagesToRender.forEach(img => {
      const imgContainer = document.createElement('div');
      imgContainer.className = 'image-container';
      
      const imgElement = document.createElement('img');
      imgElement.src = img.src;
      imgElement.alt = '缩略图';
      
      const imgInfo = document.createElement('div');
      imgInfo.className = 'image-info';
      imgInfo.textContent = `${img.naturalWidth}×${img.naturalHeight}`;
      
      const checkboxContainer = document.createElement('div');
      checkboxContainer.className = 'checkbox-container';
      
      const checkbox = document.createElement('input');
      checkbox.type = 'checkbox';
      checkbox.checked = img.selected || false;
      checkbox.addEventListener('change', function() {
        img.selected = this.checked;
      });
      
      const checkboxLabel = document.createElement('label');
      checkboxLabel.textContent = '选择';
      
      checkboxContainer.appendChild(checkbox);
      checkboxContainer.appendChild(checkboxLabel);
      
      imgContainer.appendChild(imgElement);
      imgContainer.appendChild(imgInfo);
      imgContainer.appendChild(checkboxContainer);
      
      imageGallery.appendChild(imgContainer);
    });
  }

  // 从URL中提取文件名
  function getFilenameFromUrl(url) {
    try {
      const urlObj = new URL(url);
      const pathname = urlObj.pathname;
      const filename = pathname.split('/').pop() || 'image';
      
      // 如果文件名没有扩展名,添加一个
      if (!filename.includes('.')) {
        const extension = getImageExtensionFromUrl(url);
        return `${filename}.${extension}`;
      }
      
      return filename;
    } catch {
      return 'image.jpg';
    }
  }

  // 从URL中猜测图片扩展名
  function getImageExtensionFromUrl(url) {
    if (url.includes('.jpg') || url.includes('.jpeg')) return 'jpg';
    if (url.includes('.png')) return 'png';
    if (url.includes('.gif')) return 'gif';
    if (url.includes('.webp')) return 'webp';
    if (url.includes('.svg')) return 'svg';
    if (url.includes('.bmp')) return 'bmp';
    return 'jpg'; // 默认
  }
});

// 在页面上下文中执行的函数,用于获取所有图片
function getPageImages() {
  const images = Array.from(document.querySelectorAll('img, [style*="background-image"]'));
  const result = [];
  
  images.forEach(element => {
    let src, naturalWidth, naturalHeight;
    
    if (element.tagName === 'IMG') {
      src = element.src;
      naturalWidth = element.naturalWidth;
      naturalHeight = element.naturalHeight;
    } else {
      // 处理背景图片
      const style = window.getComputedStyle(element);
      const bgImage = style.backgroundImage;
      
      if (bgImage && bgImage !== 'none') {
        src = bgImage.replace(/^url\(["']?/, '').replace(/["']?\)$/, '');
        naturalWidth = element.offsetWidth;
        naturalHeight = element.offsetHeight;
      }
    }
    
    if (src && !src.startsWith('data:') && naturalWidth > 0 && naturalHeight > 0) {
      result.push({
        src,
        naturalWidth,
        naturalHeight,
        selected: false
      });
    }
  });
  
  // 去重
  const uniqueUrls = new Set();
  return result.filter(img => {
    if (uniqueUrls.has(img.src)) return false;
    uniqueUrls.add(img.src);
    return true;
  });
}

5. 图标文件

你需要准备两个图标文件:

  • icons/icon48.png (48×48像素)
  • icons/icon128.png (128×128像素)

可以使用简单的图片作为图标,或者从免费图标网站下载。

安装和使用说明

  1. 将上述文件按照结构保存到文件夹中
  2. 在Chrome浏览器中打开 chrome://extensions/
  3. 开启"开发者模式"
  4. 点击"加载已解压的扩展程序",选择你的文件夹
  5. 插件安装完成后,点击工具栏中的插件图标即可使用

功能特点

  1. 抓取当前页面的所有图片(包括IMG标签和背景图片)
  2. 显示每张图片的尺寸信息
  3. 可按最小宽度/高度过滤图片
  4. 支持单选、全选和取消全选
  5. 批量下载选中的图片
  6. 自动为下载的图片生成合适的文件名

这个插件可以帮助用户轻松抓取网页上的所有图片资源,并通过预览选择需要的图片进行下载。


网站公告

今日签到

点亮在社区的每一天
去签到