将当前页面的网址发送到指定的服务器,服务器地址信息需要再代码中修改以适合自己使用!目前已经支持视频地址获取站点:四色AV(335pai.com),黄色仓库(hsck.net,huangsecangku.net),e-hentai.org,exhentai.org
// ==UserScript==
// @name Post Action
// @namespace https://github.com/RANSAA
// @version 0.1.0
// @description 将当前页面的网址发送到指定的服务器,服务器地址信息需要再代码中修改以适合自己使用!目前已经支持视频地址获取站点:四色AV(335pai.com),黄色仓库(hsck.net,huangsecangku.net),e-hentai.org,exhentai.org
// @author sayaDev
// @license MIT License
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAAXNSR0IArs4c6QAABXJJREFUWEfVmXtMW1Ucx7+nLS30AbRoJFsxY4hxk4CbZho02xKX6cLAIEPpDJoYn0HjI1NnjImPaCQzURNmcPqHiRlFGRHZljFlUcMkOt1whG3swUPo2P7YWmhLyy3ce8w5l0Jb+oBSRnr+aXrv+f3O5/xe59xzCBbRVhwc0SrdaVsoaDGAIoDkgdJsEOi5Wgo3CLkK0D4ApwlIp6j3to+UrvDEOyyJRzDH6iijQDVAKwAsVAcFSDMBvhu2GFsXOv6CBjNb7TsBsgug6xY6UPj+pAugn9ospob56psXcE6jvYBS7AHw8HwVL7BfGyF4Y7jK1BNLLiawudH+HCjq43B9rLFD31MQvGCrMu2LJhgV2Gy1fwLgrYWOvMj+tTaLaXckHRGBzVZ7HYCaRQ4er/hem8X0UjjhsMDLZNlQvrCWngM8HbNfxWuahMoRPB8a00HA09Wg+wYk2HznRQlBYWD1CAI2W+1HlrB0zRcytF+bzWLa5n84AywvCtgfr9YllnvCv7gEADtOJW4FSzQ+6bJZjOuZVg4s7w3oT4keJpH6CMgjbO/Bgc1WRxNAdyRygMTrIgdsFmMlYVtEhTvVHa4y6FQExbeoUGRSoev6FI6NTCaeI0TjhptVMKQQ/HNtCmM+GviWSvoJPYkUDk/la/DBei0UAXXEJwGNfQLeORn3djbmhC9VZkKjJNh1woPv+4Wg/iwsSLhVzaghOF2eyQO83yViwCVhtUGJXIOCK3jmuBtHbUtj7WjAAGoZ8Jzay9zS/KCBw33WM4EvznghUmBvsY67a3+fwIEz1ATWzQasMSp5X9u4hOrfXBh0S1ipVeD3knTu1p8vT6IyV40UBcGgW0R5uwt2gXLvfVmsw9aVaigJeNgVmlRIUSCshQG0EbPVcQGg+YG2Z8IXKo1QywaFRIGzoyK+vSigaUDg/1nrLM1Ajk7uxJ4xAK9IcceBUazSKzmwv7Fw8utrs03i2eNufHS3Fk/ma4Lk/f3DhQRALhJzg90JAtmcAW1jdgq+fkAHrSp4u3HVK2HjISfWGpVo2SKLVRxz8Ql1l2dy67x3yoNfr0zNAO/rncCH/3px5KF0FBiVPMw2HXaid0cmWGKfGxWx7agTrxWk4ZU7U7nOsMAULhYSUqS9A7N0Za4Gj+WqcVeW7CrWmgZ8uOQU8XZRGv9/fkzkv3kGJVQKoOU/Hw8lv4ULfxyFQ6DYs0GLqtUajHgk3Ns6hqEqI8+Td096uPf0KQTnKjIjAwM0LPDLa1OxM0+DK14Jj7a7uAIG0lGSAbNOwWP0h34BbxbKwJ6poPKDw8OTqDs7C5zT6OD9Pr5Hi+rbZoGHq4z8+at/jqN50MfjeOBxeRLhQ4IBhwmJ3UVpqFkju+bFP8ZxaNjHZ/93WQb/7XGIeLrDjRNlGbzPupYxXJuQONAkK339AgQRMxaOBOyvCK1DPtR0jqP0VjVPwhghMTfpbkpVcDhmVdYEkfLa6G/vd3nwzXmBu49NgFm43yXx+GS2LvvFBaePxgSuv1+Hkhw1V8viOtegnDkziJx0EbaUm7JTUFesQ6Z6FnRKAup7J1Db7ZUtm6VCw2Y9h/ZPjIXC52cmsEqvQMd22QOhFr7skXBf6xhPuINbDchPl8si8xIrfaxcvv7XOM+VkMbKWvQPTSZ8e4YS/U4R14XgWPUry9IQGDUKnojxNOZRrQoYcrP8j9pqIy7NsSSX4z1fmqNtfpYDKsqY8uaHdUiq7SVPimTbwE9bOXk+kWTgJPsInYZOns98ucDzY9XkOUjhVpaPV5PjqMpfA2OtfjeoPs/vMDAAOnmOW5fZ0vEdaM9AJ9OVgR86qS5lAhMsaa69QqtC0lwshoIvx9Xt/yOGmMNARdjRAAAAAElFTkSuQmCC
// @match http://*/*
// @match *://*/*
// @require https://update.greasyfork.org/scripts/494214/1432041/TKBaseSDK.js
// @grant unsafeWindow
// @grant GM_openInTab
// @grant GM_xmlhttpRequest
// @connect self
// @connect localhost
// @connect 127.0.0.1
// @connect *
// @compatible chrome
// @compatible edge
// @compatible firefox
// @compatible opera
// @compatible safari
// @noframes
// ==/UserScript==
/**
* 目前支持的参数:
* pageURL: 当前页面的url地址
* title: 当前网页的标题
* videoURL: pageURL页面中的视频地址,如果没有获取到视频地址则它的值与pageURL相同。
**/
// @downloadURL https://update.greasyfork.org/scripts/556061/Post%20Action.user.js
// @updateURL https://update.greasyfork.org/scripts/556061/Post%20Action.meta.js
/**
* 配置信息,可更具需求更改配置
**/
const SERVER_CONFIG = {
host: "127.0.0.1", //服务器地址
port: "80", //服务器端口,直接使用”“不指定端口
method: "POST", //请求方式
scheme: "http", //协议类型
taskAdd: "task/add", //yt-dlp 任务添加API Query Path路劲地址
};
/**
* 站点类型,不同的站点类型对应的Button不同
**/
const WebType = {
ytdlp: 0,
exhentai: 1
};
//当前站点类型样式,默认为yt-dlp样式
let currentWebType = WebType.ytdlp
/**
* 将参数组装成JSON格式
* 获取当前需要的所有属性
* pageURL: 当前页面的url地址
* title: 当前网页的标题
* videoURL: pageURL页面中的视频地址,如果没有获取到视频地址则它的值与pageURL相同。
**/
function loadParameterJSON(){
// //示例
// var json = {
// jsonrpc:'2.0',
// method:'aria2.addUri',
// id:url,
// params:[
// [url],
// ]
// }
// return JSON.stringify(json)
//网页地址
let pageURL = window.location.href;
//标题
let title = filterVideoTitle();
//视频链接
let videoURL = filterVideoLink();
let json = {
"pageURL": pageURL,
"title": title,
"videoURL":videoURL
};
return JSON.stringify(json)
}
(function() {
'use strict';
//默认为yt-dlp样式
currentWebType = WebType.ytdlp
TKBaseSDK.initToast();
addSendServerButton();
})();
// -------------------------------复写TKBaseSDK.js中的方法-------------------------------
/**
* 创建一个自定义的Button并返回。 --> TKBaseSDK.createListItemButton()方法内部有一个SVG对象,该方法没有
* text: 显示的文字
* return:button
**/
function createListItemButton(text){
// 创建一个包含按钮的DIV元素
let itemButton = document.createElement("TKButtonItem");
itemButton.setAttribute("class", "TKButtonListItemStyle");
// // 根据文字创建SVG
// let itemSVG = createSVGElement(text);
// itemSVG.setAttribute("class", "TKButtonListItemStyle");
// 将itemSVG添加到itemButton中
// itemButton.appendChild(itemSVG);
return itemButton
}
// -------------------------------复写TKBaseSDK.js中的方法-------------------------------
// -------------------------------Setup UI-------------------------------
function addSendServerButton(){
//添加style
TKBaseSDK.addButtonStyle();
//根据域名添加不同的按钮
let host = window.location.host
let exhentai = [
"e-hentai.org",
"exhentai.org",
]
//
if (exhentai.includes(host)) {
currentWebType= WebType.exhentai
setupExhentaiButton()
}else{
currentWebType= WebType.ytdlp
setupDefaultYtDlpButton()
}
}
/**
* 安装默认的yt-dlp按钮
**/
function setupDefaultYtDlpButton(){
//创建Send URL按钮
// let sendURL = TKBaseSDK.createListItemButton("Send URL");
let sendURL = createListItemButton("");
sendURL.appendChild(createIMGElement("Send URL"));
//定义的是事件被触发后要做的事情
sendURL.addEventListener("click", function() {
console.log("currentWebType:",currentWebType)
sendLocationURLAction();
});
//创建Copy URL按钮
// let copyURL = TKBaseSDK.createListItemButton("Copy URL");
let copyURL = createListItemButton("");
copyURL.appendChild(createIMGElement("Copy URL"));
//定义的是事件被触发后要做的事情
copyURL.addEventListener("click", function() {
copyLocationURLAction();
});
//创建Copy M3u8按钮
// let copyM3u8 = TKBaseSDK.createListItemButton("Copy M3U8");
let copyM3u8 = createListItemButton("");
copyM3u8.appendChild(createIMGElement("Copy M3U8"));
//定义的是事件被触发后要做的事情
copyM3u8.addEventListener("click", function() {
copyM3u8LinkAction();
});
//创建Copy yt-dlp-n按钮
// let copyYtDlpN = TKBaseSDK.createListItemButton("Copy yt-dlp-n");
let copyYtDlpN = createListItemButton("");
copyYtDlpN.appendChild(createIMGElement("Copy yt-dlp-n"));
//定义的是事件被触发后要做的事情
copyYtDlpN.addEventListener("click", function() {
copy_yt_dlp_n_M3U8LinkAction();
});
//创建Copy yt-dlp按钮
// let copyYtDlp = TKBaseSDK.createListItemButton("Copy yt-dlp");
let copyYtDlp = createListItemButton("");
copyYtDlp.appendChild(createIMGElement("Copy yt-dlp"));
//定义的是事件被触发后要做的事情
copyYtDlp.addEventListener("click", function() {
copy_yt_dlp_M3U8LinkAction();
});
//创建Copy Magnet按钮
// let copyMagnet = TKBaseSDK.createListItemButton("Copy Magnet");
let copyMagnet = createListItemButton("");
copyMagnet.appendChild(createIMGElement("Copy Magnet"));
copyMagnet.addEventListener("click", function() {
copyMagnetLinksAction();
});
let list = document.createElement("TKButtonList");
list.className = "TKButtonListStyle";
list.appendChild(sendURL);
//list.appendChild(copyURL);
list.appendChild(copyM3u8);
list.appendChild(copyYtDlpN);
list.appendChild(copyYtDlp);
//list.appendChild(copyMagnet);
document.body.appendChild(list);
}
/**
* 安装exhentai站点对应的按钮
**/
function setupExhentaiButton(){
//创建Send URL按钮
// let sendURL = TKBaseSDK.createListItemButton("Send URL");
let sendURL = createListItemButton("");
sendURL.appendChild(createIMGElement("Send URL"));
//定义的是事件被触发后要做的事情
sendURL.addEventListener("click", function() {
console.log("currentWebType:",currentWebType)
sendLocationURLAction();
});
//创建Copy hentai按钮
// let copyHentai = TKBaseSDK.createListItemButton("Copy yt-dlp-n");
let copyHentai = createListItemButton("");
copyHentai.appendChild(createIMGElement("Copy hentai"));
//定义的是事件被触发后要做的事情
copyHentai.addEventListener("click", function() {
copy_hentai_Action();
});
//创建Copy hentai按钮
// let copyHentai = TKBaseSDK.createListItemButton("Copy yt-dlp-n");
let copyHentaiN = createListItemButton("");
copyHentaiN.appendChild(createIMGElement("Copy hentai-n"));
//定义的是事件被触发后要做的事情
copyHentaiN.addEventListener("click", function() {
copy_hentai_AtlasName_Action();
});
//创建Copy copyHentaiName按钮
// let copyHentaiName = TKBaseSDK.createListItemButton("Copy yt-dlp-n");
let copyHentaiName = createListItemButton("");
copyHentaiName.appendChild(createIMGElement("Copy Title"));
//定义的是事件被触发后要做的事情
copyHentaiName.addEventListener("click", function() {
copy_hentai_name_Action();
});
let list = document.createElement("TKButtonList");
list.className = "TKButtonListStyle";
// list.appendChild(sendURL);
list.appendChild(copyHentaiN);
// list.appendChild(copyHentai);
// list.appendChild(copyHentaiName);
document.body.appendChild(list);
}
// -------------------------------Setup UI-------------------------------
// -------------------------------Action-------------------------------
/**
* 发送数据当前页面的URL到指定服务器
*/
function sendLocationURLAction()
{
console.log(`Send Server`);
//服务器的地址
var serverUrl = SERVER_CONFIG.scheme + "://" + SERVER_CONFIG.host + ":" + SERVER_CONFIG.port + "/" + SERVER_CONFIG.taskAdd;
if (SERVER_CONFIG.port === "" ) {
serverUrl = SERVER_CONFIG.scheme + "://" + SERVER_CONFIG.host + "/" + SERVER_CONFIG.taskAdd;
}
//发送的参数数据
let data = loadParameterJSON();
console.log(`serverUrl: ${serverUrl}`);
console.log(`parameter: ${data}`);
//GM_xmlhttpRequest方式请求
GM_xmlhttpRequest({
method: SERVER_CONFIG.method,
url: serverUrl,
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
data: data,
onload: function(response) {
console.log(response);
console.log(`readyState:${response.readyState}`);
console.log(`status:${response.status}`);
console.log(`statusText:${response.statusText}`);
console.log(`responseHeaders:\n${response.responseHeaders}`);
console.log(`responseText:${response.responseText}`);
if (response.status === 200) {
console.log(`Send URL Success: ${url}`);
TKBaseSDK.showToast("当前URL地址发送成功!",1);
} else {
console.log(`Send URL Error: ${url} statusText: ${response.statusText}`);
TKBaseSDK.showToast("当前URL地址发送失败!",0);
}
},
onerror: function(response) {
// 请求发生错误时执行
console.error("Request failed:", response);
let msg = `发送失败,Send Server服务地址:${response.finalUrl}`;
console.log(msg);
TKBaseSDK.showToastWtihTime(msg, 0, 4000);
}
});
}
/**
* 拷贝当前网页地址
**/
function copyLocationURLAction(){
//当前网页地址
let url = window.location.href;
TKBaseSDK.copyToClipBoard(url);
TKBaseSDK.showToast("复制成功!",1);
}
/**
* 获取并拷贝m3u8链接
**/
function copyM3u8LinkAction(){
let m3u8URL = filterVideoLink();
if (m3u8URL === "" || m3u8URL === window.location.href) {
TKBaseSDK.showToast("复制失败,没有找到M3U8链接!",0);
TKBaseSDK.copyToClipBoard("");
}else{
TKBaseSDK.showToast("复制成功!",1);
//拷贝到剪切板
TKBaseSDK.copyToClipBoard(m3u8URL);
}
}
/**
* 拷贝四色AV中的标题与m3u8链接,并且组装yt-dlp-n命令
* 格式: yt-dlp-n "视频标题" "m3u8视频地址"
**/
function copy_yt_dlp_n_M3U8LinkAction(){
let videoURL = filterVideoLink();
let title = filterVideoTitle();
if (videoURL === "" || title === "") {
TKBaseSDK.showToast("yt-dlp-n下载命令复制失败,没有找到视频链接!",0);
TKBaseSDK.copyToClipBoard("");
}else{
TKBaseSDK.showToast("yt-dlp-n下载命令复制成功!",1);
//拷贝到剪切板
let cmd = "yt-dlp " + "\"" + title + "\"" + " \"" + videoURL + "\"" + "";
TKBaseSDK.copyToClipBoard(cmd);
}
}
/**
* 拷贝当前网页链接, 并组装yt-dlp命令
* 格式:yt-dlp "网页地址"
**/
function copy_yt_dlp_M3U8LinkAction(){
let videoURL = filterVideoLink();
TKBaseSDK.showToast("yt-dlp下载命令复制成功!",1);
//拷贝到剪切板
let cmd = "yt-dlp " + "\"" + videoURL + "\"" + "";
TKBaseSDK.copyToClipBoard(cmd);
}
/**
* 功能:拷贝当前页面的所有magnet磁力链接
**/
function copyMagnetLinksAction(){
const magnetLinks = getMagnetLinks();
// 转换成换行分隔的字符串
const magnetLinksString = magnetLinks.join('\n');
if (magnetLinksString === "" ) {
TKBaseSDK.showToast("Copy Mangnet失败,没有找到磁力链接!",0);
TKBaseSDK.copyToClipBoard("");
}else{
TKBaseSDK.showToast("Copy Mangnet成功!",1);
//拷贝到剪切板
TKBaseSDK.copyToClipBoard(magnetLinksString);
}
}
/**
* 功能:拷贝e-hentai.org,exhentai.org站点的hentai下载链接 与 当前图集的名称
**/
function copy_hentai_AtlasName_Action(){
//当前网页地址
let url = window.location.href;
console.log("url:",url)
//当前页面图集的标题
let title = window.document.title;
// 移除末尾的 "- E-Hentai Galleries"
title = title.replace(/\s*-\s*E-Hentai Galleries$/i, '').trim();
// 处理文件名中的特殊字符
title = sanitizeFileName(title);
console.log("title:",title)
//当前图集图片数量
let picCount = hentai_getAlbumPicCount()
console.log("picCount:",picCount)
//拷贝到剪切板
let cmd = "hentai -u " + "\"" + url + "\"" + " -n " + "\"" + title + "\"" + " -s "+ "-r ";
if (picCount != null){
cmd = "hentai -u " + "\"" + url + "\"" + " -n " + "\"" + title + "\"" + " -t " + picCount + " -s "+ "-r ";
}
TKBaseSDK.copyToClipBoard(cmd);
TKBaseSDK.showToast("hentai-n下载命令复制成功!",1);
}
/**
* 功能:拷贝e-hentai.org,exhentai.org站点的hentai下载链接
**/
function copy_hentai_Action(){
//当前网页地址
let url = window.location.href;
TKBaseSDK.showToast("hentai下载命令复制成功!",1);
//拷贝到剪切板
let cmd = "hentai -u " + "\"" + url + "\"" + " -s "+ "-r ";
TKBaseSDK.copyToClipBoard(cmd);
}
/**
* 获取e-hentai.org,exhentai.org站点当前图集的名称
**/
function copy_hentai_name_Action(){
let title = window.document.title;
// 移除末尾的 "- E-Hentai Galleries"
title = title.replace(/\s*-\s*E-Hentai Galleries$/i, '').trim();
// 处理文件名中的特殊字符
title = sanitizeFileName(title);
TKBaseSDK.copyToClipBoard(title);
// TKBaseSDK.showToast("当前图集名称复制成功!",1);
// let msg = "图集名称[" + title + "]复制成功!"
let msg = "图集名称:" + title
TKBaseSDK.showToast(msg,1);
}
// -------------------------------Action-------------------------------
// -------------------------------解析视频地址和标题-------------------------------
/**
* 过滤获取当前视频指定的名称
**/
function filterVideoTitle(){
// 默认使用网站标题作为title
var title = document.title;
//匹配四色AV站点标题
let fourColorAVTitle = getFourColorAVTitle();
if (fourColorAVTitle) {
title = fourColorAVTitle;
}
//匹配黄色仓库
let hsckTitle = getHuangSeCangKuTitle();
if (hsckTitle) {
title = hsckTitle;
}
//匹配其它站点...
//去掉字符串两端的空格和不可见字符(例如空格、换行、制表符等)
title = title.trim();
// 处理文件名中的特殊字符
title = sanitizeFileName(title);
return title
}
/**
* 过滤并获取视频地址,如果没有获取到视频地址则直接使用window.location.href
**/
function filterVideoLink(){
// 默认使用当前页面地址
var videoURL = window.location.href;
//获取四色AV的视频地址
let fourColorAVURL = getFourColorAVM3u8Url();
if (fourColorAVURL) { // 等效 fourColorAVURL !== ""
videoURL = fourColorAVURL;
}
// 黄色仓库
let hsckVideoURL = getHuangSeCangKuM3U8Url();
if (hsckVideoURL) {
videoURL = hsckVideoURL;
}
//其它站点...
return videoURL
}
/**
* 获取四色AV中的m3u8链接地址
**/
function getFourColorAVM3u8Url(){
// // Define a regular expression to match the playUrl variable pattern
// const playUrlPattern = /var playUrl\s*=\s*"([^"]+)"/;
// // Get all script tags on the page
// const scripts = Array.from(document.getElementsByTagName('script'));
// // Look for the script containing the playUrl variable
// const matchedScript = scripts.find(script => playUrlPattern.test(script.textContent));
// var m3u8Url = ""
// // If found, extract the URL
// if (matchedScript) {
// const match = matchedScript.textContent.match(playUrlPattern);
// m3u8Url = match && match[1];
// //将域名占位符转换正真正的主机 - 已弃用:不能写死
// m3u8Url = m3u8Url.replace(/\+\@movivecom\@\+/g, "qfvgzy.com");
// console.log('四色AV站点:m3u8 URL:', m3u8Url);
// } else {
// console.warn('四色AV站点:m3u8 URL could not be found.');
// }
var m3u8Url = ""
// 获取地址的新方法
// 判断变量playUrl是否存在, 直接获取playUrl变量的值。
if (typeof playUrl !== "undefined") {
m3u8Url = playUrl;
}
m3u8Url = m3u8Url.trim();
console.log('四色AV站点:m3u8 URL:', m3u8Url);
return m3u8Url
}
/**
* 获取四色AV中视频的标题
**/
function getFourColorAVTitle(){
var title = ""
// 获取包含 h1 元素的 div.main 元素
const mainDiv = document.querySelector('.wrap > .main');
// 确认 main 元素存在
if (mainDiv) {
// 在 mainDiv 内查找 h1 元素
const h1Element = mainDiv.querySelector('h1');
// 确认 h1 元素存在
if (h1Element) {
// 获取 h1 元素的文本内容
const h1Content = h1Element.textContent.trim();
console.log('四色AV站点:查找h1 内容为:', h1Content);
title = h1Content
} else {
console.warn('四色AV站点:查找视频标题时未找到 h1 元素!');
}
} else {
console.warn('四色AV站点:查找视频标题时未找到 .main 元素!');
}
return title
}
/**
* 获取黄色仓库的视频地址
* 站点1:huangsecangku.net
* 站点2:hsck.net
* 站点3:hsck.app
**/
function getHuangSeCangKuM3U8Url(){
var m3u8Url = "";
// 判断变量player_aaaa.url是否存在,并且直接根据player_aaaa.url的值来获取视频地址
if (typeof player_aaaa !== "undefined" && player_aaaa.url !== undefined) {
m3u8Url = player_aaaa.url;
}
m3u8Url = m3u8Url.trim();
console.log('黄色仓库站点:m3u8 URL:', m3u8Url);
return m3u8Url;
}
/**
* 获取黄色仓库标题
**/
function getHuangSeCangKuTitle(){
var title = ""
/**
* trim():去掉字符串两端的空格和不可见字符(例如空格、换行、制表符等)
* if (text) 自动判断 null, undefined, ""
**/
const quearyTitle = document.querySelector(".stui-warp-content h3.title")?.textContent?.trim();
if (quearyTitle) {//查询到的表示有效
title = quearyTitle;
}
console.log('黄色仓库站点:Video Title:', title);
return title
}
/**
* 获取页面中的所有magnet磁力链接
**/
function getMagnetLinks(){
// 从整个 HTML 文档中提取磁力链接
const htmlContent = document.documentElement.innerHTML;
const magnetRegex = /magnet:\?xt=urn:[a-zA-Z0-9:]+/g;
const magnetLinks = Array.from(new Set(htmlContent.match(magnetRegex) || []));
console.log(magnetLinks);
return magnetLinks;
}
// -------------------------------解析视频地址和标题-------------------------------
// -------------------------------hentai e-xhentai.org 站点资源解析-------------------------------
/**
* 获取当前图集图片数量
**/
function hentai_getAlbumPicCount(){
const cells = document.querySelectorAll('td.gdt2');
for (let cell of cells) {
const text = cell.textContent.trim();
if (/pages|页/i.test(text)) {
const match = text.match(/\d+/);
if (match) return parseInt(match[0], 10);
}
}
return null;
}
// -------------------------------hentai e-xhentai.org 站点资源解析-------------------------------
// -------------------------------处理文件名合规性-------------------------------
/**
* 功能:将字符串中不能作为文件名的字符替换成"_",并且如果存在英文的双引号"替换成英文的单引号'
* replace(/"/g, '“'); //正则表达式
* replaceAll('"', '“'); //直接替换函数
**/
function sanitizeFileName(filename) {
//使用正则表达式将"替换成'
var name = filename;
//去掉字符串两端的空格和不可见字符(例如空格、换行、制表符等)
name = name.trim();
name = name.replace(/"/g, "'"); //注意:这儿使用的正则表达式无法将"替换成',然后再调用这个函数的外部直接对字符串操作又可以,不知道是什么原因。所以直接使用replaceAll方法进行替换。
name = name.replaceAll('"', "'");
name = name.replaceAll(':', ":");
name = name.replaceAll('”', "'");
name = name.replaceAll('!', "!");
// name = name.replaceAll('/', "|");
name = name.replaceAll('/', "⁄");
//将不能作为文件名的字符替换为:_
name = name.replace(/[:]+/g, '_'); // -osx
// name = name.replace(/[\/\\:*?"<>|]+/g, '_'); // win
return name
}
/**
* 功能:将字符串中不能作为路径的字符替换成”_“
**/
function sanitizePath(path) {
return path.replace(/[\/\\:*?"<>|]+/g, '_'); // 替换为单个下划线
}
// -------------------------------处理文件名合规性-------------------------------
// -------------------------------文字生成图片-------------------------------
/**
* 功能:将文字生成PNG图片
* text: 文字内容
* width: 图片宽度
* height: 图片高度
* 使用示例:
const img = document.createElement("img");
img.src = textToImage("Copy yt-dlp-n",128,44);
document.body.appendChild(img);
**/
function textToImage(text, width, height) {
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
// 设置背景填充颜色,需要执行fillRect,fill等方法才会生效
ctx.fillStyle = "#1ca7ee";
// // 填充背景为矩形
// ctx.fillRect(0, 0, 44, 44);
// // 填充背景为圆形
// // 获取圆形半径(取宽高中的最小值的一半)
// const radius = Math.min(width, height) / 2;
// const centerX = width / 2;
// const centerY = height / 2;
// ctx.beginPath();
// ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
// ctx.fill();
// 绘制文字
ctx.fillStyle = "#fff";
ctx.font = "700 14px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
// ✅文字绘制在画布中心
ctx.fillText(text, canvas.width / 2, canvas.height / 2);
return canvas.toDataURL("image/png");
}
/**
* 功能:创建128x44的IMG对象
* text:图片显示的内容
**/
function createIMGElement(text) {
let imgItem = document.createElement("img");
imgItem.src = textToImage(text,128,44);
return imgItem;
}
// -------------------------------文字生成图片-------------------------------