Greasy Fork is available in English.
获取指定网站上的所有图片链接,并将其合成为 PDF 文件
// ==UserScript==
// @name 行业标准信息服务平台PDF下载
// @namespace https://tampermonkey.net/
// @version 0.1
// @description 获取指定网站上的所有图片链接,并将其合成为 PDF 文件
// @author 笔墨纸砚
// @match *://hbba.sacinfo.org.cn/attachment/onlineRead/*
// @grant none
// @license MIT
// @require https://cdn.staticfile.org/jspdf/2.5.1/jspdf.umd.min.js
// @require https://cdn.staticfile.org/html2canvas/1.4.1/html2canvas.min.js
// ==/UserScript==
(async () => {
'use strict';
async function fetchImage(pageNumber) {
const url = `${window.location.href}/${pageNumber}.png`.replace('attachment/onlineRead','hbba_onlineRead_page');
//https://hbba.sacinfo.org.cn/attachment/onlineRead/
//https://hbba.sacinfo.org.cn/hbba_onlineRead_page/
const headers = {
'Accept': 'image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Cache-Control': 'no-cache',
'Pragma': 'no-cache',
'Referer': `${window.location.href}`,
'Sec-Fetch-Dest': 'image',
'Sec-Fetch-Mode': 'no-cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.48',
'Cookie': document.cookie,
};
try {
const response = await fetch(url, { headers });
if (!response.ok) {
if (response.status === 404) {
return null;
}
throw new Error(`Failed to fetch image ${url}`);
}
return response.url;
} catch (error) {
//console.error(`Image fetch error: ${url}`, error);
return null;
}
}
async function fetchImagesBatch(startPage, batchSize) {
const fetchPromises = Array.from({ length: batchSize }, (_, i) => fetchImage(startPage + i));
const srcList = await Promise.all(fetchPromises);
return srcList.filter(src => src !== null);
}
async function fetchAllImages() {
const batchSize = 50;
let currentPage = 0;
let allSrcList = [];
let maxPageNumber = 0;
while (true) {
const srcList = await fetchImagesBatch(currentPage, batchSize);
if (srcList.length === 0) {
break;
}
allSrcList = allSrcList.concat(srcList);
const lastPageNumber = currentPage + srcList.length - 1;
if (lastPageNumber > maxPageNumber) {
maxPageNumber = lastPageNumber;
}
currentPage += batchSize;
}
console.log(`最大页码为:${maxPageNumber}`);
return allSrcList;
}
async function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = src;
img.crossOrigin = "Anonymous";
img.onload = () => resolve(img);
img.onerror = (error) => reject(error);
});
}
async function imagesToPDF(srcList) {
const pdf = new jspdf.jsPDF({unit: 'px'});
const length = srcList.length;
for (let i = 0; i < length; i++) {
const imgSrc = srcList[i];
try {
const img = await loadImage(imgSrc);
const pageWidth = pdf.internal.pageSize.getWidth();
const pageHeight = pdf.internal.pageSize.getHeight();
const imgAspectRatio = img.width / img.height;
let imgWidth = pageWidth;
let imgHeight = pageWidth / imgAspectRatio;
if (imgHeight > pageHeight) {
imgHeight = pageHeight;
imgWidth = pageHeight * imgAspectRatio;
}
pdf.addImage(img, 'JPEG', 0, 0, imgWidth, imgHeight);
if (i < length - 1) {
pdf.addPage();
}
} catch (error) {
console.error(`图片加载失败:${imgSrc}`, error);
}
}
pdf.save('ImagesToPDF.pdf');
}
function createButton() {
const btn = document.createElement('button');
btn.innerHTML = '合成PDF';
btn.style.position = 'fixed';
btn.style.top = '50%';
btn.style.right = '20px';
btn.style.transform = 'translateY(-50%)';
btn.style.zIndex = '10000';
btn.style.backgroundColor = '#4CAF50';
btn.style.border = 'none';
btn.style.borderRadius = '5px';
btn.style.color = 'white';
btn.style.fontSize = '16px';
btn.style.padding = '12px 24px';
btn.style.cursor = 'pointer';
btn.addEventListener('click', async () => {
const srcList = await fetchAllImages();
imagesToPDF(srcList);
});
document.body.appendChild(btn);
}
createButton();
})();