// ==UserScript==
// @name 孔夫子旧书网无水印图片下载助手
// @description 一键批量下载孔夫子旧书网商品图片(无水印版本)
// @version 1.0.0
// @author 骄阳哥
// @namespace jyg
// @match *://search.kongfz.com/product_result/*
// @match *://book.kongfz.com/*
// @match *://item.kongfz.com/book/*
// @grant GM_addStyle
// @grant GM_download
// @grant GM_xmlhttpRequest
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 当前页面URL
const currentUrl = window.location.href;
// 移除图片水印
function removeImageWatermark(imgUrl) {
return imgUrl.replace(/(_water|_n|_p|_b|_s)/g, '');
}
// 创建商品详情页下载按钮
function createDetailPageButton(images) {
const btn = document.createElement('button');
btn.innerText = `📥 下载全部图片(${images.length}张)`;
btn.id = 'kfz-download-btn';
btn.style.backgroundColor = '#1890ff';
btn.style.color = 'white';
document.body.appendChild(btn);
return btn;
}
// 创建搜索页面下载按钮
function createSearchPageButton(doc, item) {
const btn = doc.createElement('button');
btn.innerText = '📥 下载图片';
btn.className = 'kfz-search-download-btn';
btn.style.backgroundColor = '#1890ff';
const cartBtn = item.querySelector('div.add-cart-btn');
cartBtn.parentNode.insertBefore(btn, cartBtn);
return btn;
}
// 创建书籍列表页下载按钮
function createListPageButton(doc, item) {
const btn = doc.createElement('button');
btn.innerText = '📥 下载图片';
btn.className = 'kfz-list-download-btn';
btn.style.backgroundColor = '#1890ff';
const cartBtn = item.querySelector('a.con-btn-cart');
cartBtn.parentNode.insertBefore(btn, cartBtn.nextSibling);
return btn;
}
// 获取商品图片列表
function getBookImages(doc) {
const imgItems = doc.querySelectorAll('ul#figure-info-box > li');
return Array.from(imgItems, item => {
const img = item.querySelector('img');
const imgSrc = img ? img.getAttribute('_viewsrc') : null;
return removeImageWatermark(imgSrc);
});
}
// 下载图片
function downloadImages(doc, btn) {
const images = getBookImages(doc);
if(images.length === 0) {
console.warn('未找到可下载的图片');
btn.innerText = '😅 暂无可下载的图片';
btn.style.backgroundColor = '#999';
btn.disabled = true;
return;
}
console.log(`找到${images.length}张图片待下载:`, images);
btn.disabled = true;
btn.innerText = '下载中...';
let successCount = 0;
let failCount = 0;
// 获取书名和ISBN
const bookName = doc.querySelector('h1')?.innerText || '未知书名';
const isbnInfo = doc.querySelector('meta[name="description"]').getAttribute('content').match(/ISBN:([0-9]*)/);
const isbn = isbnInfo?.[1] || '';
console.log('书籍信息:', {
bookName,
isbn
});
// 下载每张图片
images.forEach((imgUrl, index) => {
if(!imgUrl) {
console.error(`第${index + 1}张图片URL无效`);
failCount++;
return;
}
const downloadWithRetry = (url, hasWatermark = false) => {
const ext = url.split('.').pop()?.toLowerCase() || 'jpg';
const watermarkText = hasWatermark ? '-有水印' : '';
const fileName = `${bookName.trim()}-${isbn.trim()}-${index + 1}${watermarkText}.${ext}`;
console.log(`开始下载第${index + 1}张图片:`, {
url,
fileName,
hasWatermark
});
GM_download({
url,
name: fileName,
onload: () => {
successCount++;
console.log(`第${index + 1}张图片下载成功:`, {
url,
fileName,
successCount,
total: images.length
});
btn.innerText = `下载中...(${successCount}/${images.length})`;
if(successCount === images.length) {
console.log('所有图片下载完成!');
btn.innerText = `✅ ${successCount}张图片已下载`;
btn.style.backgroundColor = '#52c41a';
}
},
onerror: (err) => {
if(!hasWatermark) {
// 无水印版本下载失败,尝试下载带水印版本
console.log(`第${index + 1}张无水印图片下载失败,尝试下载带水印版本:`, {
url,
error: err
});
const watermarkUrl = url.replace(/\.([^.]*)$/, '_b.$1');
downloadWithRetry(watermarkUrl, true);
} else {
// 带水印版本也下载失败
failCount++;
console.error(`第${index + 1}张图片下载失败(带水印版本):`, {
url,
error: err,
failCount,
total: images.length
});
btn.innerText = `❌ ${failCount}张图片下载失败`;
if(err.error) {
console.error('错误详情:', err.error);
}
}
}
});
};
// 开始下载无水印版本
downloadWithRetry(imgUrl);
});
}
// 从URL获取并下载图片
function downloadFromUrl(url, btn) {
btn.addEventListener('click', () => {
console.log('开始获取页面:', url);
GM_xmlhttpRequest({
method: 'GET',
url: url,
onload: response => {
console.log('页面获取成功:', {
url,
status: response.status
});
const parser = new DOMParser();
const doc = parser.parseFromString(response.responseText, 'text/html');
downloadImages(doc, btn);
},
onerror: err => {
console.error('页面获取失败:', {
url,
error: err
});
btn.innerText = '❌ 获取图片失败';
}
});
});
}
// 处理搜索页面
function handleSearchPage(item) {
const link = item.querySelector('.item-info > .title > a');
const btn = createSearchPageButton(document, item);
downloadFromUrl(link.href, btn);
}
// 处理列表页面
function handleListPage(item) {
const link = item.querySelector('div.list-con-title > a');
const btn = createListPageButton(document, item);
downloadFromUrl(link.href, btn);
}
// 初始化页面
let checkInterval;
if(currentUrl.includes('book.kongfz.com')) {
const btn = createDetailPageButton(getBookImages(document));
btn.addEventListener('click', () => downloadImages(document, btn));
}
else if(currentUrl.includes('search.kongfz.com/product_result')) {
checkInterval = setInterval(() => {
const listBox = document.querySelector('#listBox');
if(listBox) {
clearInterval(checkInterval);
document.querySelectorAll('#listBox .item')
.forEach(item => handleSearchPage(item));
}
}, 1000);
}
else if(currentUrl.includes('item.kongfz.com/book')) {
checkInterval = setInterval(() => {
const listBox = document.querySelector('ul.itemList');
if(listBox) {
clearInterval(checkInterval);
document.querySelectorAll('ul.itemList > li')
.forEach(item => handleListPage(item));
}
}, 1000);
}
// 注入样式
GM_addStyle(`
#kfz-download-btn {
position: fixed;
bottom: 30px;
right: 30px;
padding: 12px 24px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
transition: all 0.3s;
z-index: 9999;
}
#kfz-download-btn:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}
.kfz-search-download-btn,
.kfz-list-download-btn {
padding: 4px 12px;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
margin: 0 8px;
transition: all 0.3s;
}
.kfz-search-download-btn:hover,
.kfz-list-download-btn:hover {
opacity: 0.8;
}
button:disabled {
background-color: #999 !important;
cursor: not-allowed;
opacity: 0.7;
}
`);
})();