// ==UserScript==
// @name 超星图文数据共享(cjwk)
// @namespace http://tampermonkey.net/
// @version 1.0.9
// @description 把页面上的部分信息抽取成JSON并放入剪切板,参考文件直接粘贴源数据,无需处理。
// @author Ade
// @license MIT
// @match https://qikan.chaoxing.com/detail_*
// @grant GM_setClipboard
// @require https://code.jquery.com/jquery-1.11.min.js
// ==/UserScript==
(function() {
'use strict';
console.log('进入插件')
class InitMethods {
constructor(){
this.imgList = []// 假设给定的数组名为data,包含多个对象,每个对象有imgurl和title属性
this.newImageData = []// 定义一个空数组用于存储上传后的图片对象
}
//获取图文原始数据源
getBasicData(){
this.imgList = [];
let dl = $('.clearfix.articleImg dl');
if(!dl.length){
alert('暂无可复制数据')
return $('.cjwk_copy_btn_img').hide()//没有图文不显示复制按钮
}
$("#overlay, #popup").fadeIn();
let _this = this;//在 JavaScript 中,each 方法无法直接访问构造函数(constructor)中的 this,下面如果使用箭头函数那么jq的$就失效,就是上下文的问题
dl.each(function() {
let url = $(this).find('img').attr('src');
let text = $(this).find('a').text();
let imgObj = {};
imgObj.imgurl = url;
imgObj.title = text;
_this.imgList.push(imgObj);
//处理本地数据异步问题,数据抓取完成再执行上传
if(_this.imgList.length==dl.length){
console.log('原始数据:',_this.imgList)
_this.asyncNewImg();
}
});
}
getDirectoryData(){
// 获取菜单的HTML代码
// const menuElement = document.querySelector('.muluBox');
//const menuListNode = menuElement.querySelector('ul');
//const menuListNode = $('.muluBox>ul')
const menuList = $('.muluBox>ul>li');
const menuData = { data: { menus: [] } };
for (let i = 0; i < menuList.length; i++) {
const menuItem = menuList[i];
const link = menuItem.querySelector('a');
const menuText = link.innerText.trim();
let currentMenu = null;
if (menuItem.querySelector('ul')) {
// Parent menu item with sub-menu
const subMenuItems = menuItem.querySelectorAll('ul > li');
const menuChildren = [];
for (let j = 0; j < subMenuItems.length; j++) {
const subMenuItem = subMenuItems[j];
const subLink = subMenuItem.querySelector('a');
const subMenuText = subLink.innerText.trim();
menuChildren.push({ text: subMenuText });
}
currentMenu = { text: menuText, children: menuChildren };
} else {
// Single menu item
currentMenu = { text: menuText };
}
menuData.data.menus.push(currentMenu);
}
//const _menuData = {
// data:{
// menus:Array.from(new Set(menuData.data.menus))
// }
// };
GM_setClipboard(JSON.stringify(menuData), 'text');
alert('目录数据处理成功,已复制')
console.log(menuData)
return JSON.stringify(menuData);
}
//定义一个函数用于上传图片并返回服务地址
uploadImage(imgurl) {
// 返回一个Promise对象,模拟异步操作
return new Promise((resolve, reject)=> {
// 创建一个FormData对象,用于发送图片数据
let formData = new FormData();
formData.append('fileUrl', imgurl);
// 创建一个XMLHttpRequest对象
let xhr = new XMLHttpRequest();
// 监听上传过程的状态变化
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
// 图片上传成功,解析返回的服务地址
let response = JSON.parse(xhr.responseText);
let serviceUrl = response.fileName;
// 将服务地址传递给Promise对象的回调函数
resolve(serviceUrl);
} else {
// 图片上传失败,将错误信息传递给Promise对象的回调函数
reject(xhr.statusText);
}
}
};
// 打开一个POST请求,将图片数据发送到上传接口
xhr.open('POST', 'https://wkapi.cjwk.cn/show/common/applyByUrl');
// 发送FormData对象
xhr.send(formData);
});
}
//异步改为同步处理网络图片,确保图片顺序一致
async asyncNewImg() {
if(this.newImageData.length>0){
console.error('兄弟,慢点搞,服务器顶不住')
}
this.newImageData = [];
for (let i = 0; i < this.imgList.length; i++) {
try {
const serviceUrl = await this.uploadImage(this.imgList[i].imgurl);
let newImage = {
serviceUrl: serviceUrl,
title: this.imgList[i].title
};
this.newImageData.push(newImage);
if (this.newImageData.length === this.imgList.length) {
$("#overlay, #popup").fadeOut();
GM_setClipboard(JSON.stringify(this.newImageData), 'text');
console.log(this.newImageData)
setTimeout(()=>{alert('图文数据处理成功,已复制')},500)
}
} catch (error) {
alert('上传接口服务异常,多次尝试无果可联系危桑老师')
console.error('危桑,图片上传失败咋办:', error);
}
}
}
//创建自定义弹窗样式区域
setCssDom_Fn(){
//<button class='cjwk_copy_btn_all' title='复制图文和参考文献'>复制图文和参考文献</button>
let _copy = `<div class='btn_warp'>
<button class='cjwk_copy_btn_men' title='复制目录'>复制目录</button>
<button class='cjwk_copy_btn_img' title='复制图片和标题'>复制图文</button>
<button class='cjwk_copy_btn_cat' title='复制参考文献'>复制参考文献</button>
<button class='cjwk_copy_btn_authorsUnit' title='复制作者单位'>复制作者单位</button>
</div>`;
$('.readMulu').append(_copy);
// 创建一个 <style> 元素
var style = document.createElement('style');
style.type = 'text/css';
// 定义 CSS 样式
var css = `
/* 在这里编写你的 CSS 样式 */
#overlay {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: none;
}
#popup {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
display: none;
}
#popup h2 {
margin-top: 0;
color:green;
-webkit-animation: flash 1s linear infinite;
animation: flash 1s linear infinite;
}
#closeBtn {
margin-top: 10px;
}
.btn_warp{
position: fixed;
display:flex;
flex-direction: column;
left: 280px;
top: 43%;
}
.btn_warp>button{
background-color: #f98c51;
display: inline-block;
height: 32px;
width: auto;
padding: 0 10px;
font-size: 14px;
text-indent: 0;
text-align: center;
color: #fff;
line-height: 32px;
font-family: Microsoft Yahei,serif;
border-radius: 4px;
overflow: visible;
cursor:pointer;
border:1px solid #ccc;
margin-bottom:10px;
}
button.cjwk_copy_btn_img{
background-color: #596adf;
}
button.cjwk_copy_btn_cat{
background-color: #d759df;
}
@-webkit-keyframes flash {
0% {
opacity: 1;
}
50% {
opacity: 0.1;
}
to {
opacity: 1;
}
}
@keyframes flash {
0% {
opacity: 1;
}
50% {
opacity: 0.1;
}
to {
opacity: 1;
}
}
`;
// 将 CSS 样式添加到 <style> 元素中
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
// 将 <style> 元素插入到页面的 <head> 中
document.head.appendChild(style);
let alertDom = `<button id="openBtn">打开弹窗</button>
<div id="overlay"></div>
<div id="popup">
<h2>疯狂处理中,请稍后......</h2>
</div>`
$('body').append(alertDom);
}
//获取参考文献
getLiteratureData(type=0){
var result = '';
var startElement = $('[data-meta-name="参考文献"]').length?$('[data-meta-name="参考文献"]'):$('[class="reference"]');
var endElement = $('.title_translate');
var currentElement = startElement.next(); // 获取下一个兄弟元素
while (currentElement.length && !currentElement.is(endElement)) {
result += currentElement.text().trim() + '\n'; // 获取文本内容并添加换行符
currentElement = currentElement.next(); // 获取下一个兄弟元素
}
GM_setClipboard(result, 'text');
if(result.length){
alert('文献数据处理成功,已复制')
console.log(result)
}else{
alert('err,数据处理失败,请联系管理员')
}
return result||''
let texts = [];
if(type){ //默认只获取 [x] 这种开头的参考文献
const regex = /^\[\d+\].*$/;
$("p.content[name^='ref']")?.map(function() {
let text = $(this).text();
//return text.match(regex) ? text : ""+'\n';
if(text.match(regex)){
//texts+=text+'\n';
texts.push(text);
}
}).get();
}else{ //这是全部参考文献
$("p.content[name^='ref']")?.map(function(item,index) {
texts.push($(this).text());
}).get();
}
const _texts = Array.from(new Set(texts))?.join('\n')
GM_setClipboard(_texts, 'text');
alert('文献数据处理成功,已复制')
console.log(texts)
return _texts||''
}
parseArticlesAuthorsUnit() {
let author_querySelector_1 = document.querySelectorAll('.F_name sup');
let author_querySelector_2 = document.querySelectorAll('.F_name')[0];
let unit_querySelector_1 = document.querySelectorAll('.Fmian1 td:nth-child(2) sup');
let unit_querySelector_2 = document.querySelectorAll('.Fmian1 td:nth-child(2)')[0];
let authorElements = author_querySelector_1.length?author_querySelector_1:[author_querySelector_2];
let unitElements = unit_querySelector_1.length?unit_querySelector_1:[unit_querySelector_2];
function isSignal(arr){//判断作者名是否包含,
let newAuthorName = [],authorName = '';
for (let i = 0; i < arr.length; i++) {
if(arr[i].innerText.includes(',')||arr[i].innerText.includes(',')){//三种情况,一个作者多个单位,多个作者多个单位,多个作者一个单位
let cn_en_str = ','
if(arr[i].innerText.includes(',')){
cn_en_str = ','
}else{
cn_en_str = ','
}
newAuthorName = [...newAuthorName,...splitauth(arr[i],cn_en_str)]
}else{
let obj = {
authorName:getName(arr[i]),
serial:Number(arr[i].innerText)||1//单位标记,
}
newAuthorName.push(obj)
}
}
return newAuthorName;
}
function getName(str){//获取字符值
const _str = str?.previousSibling?.nodeValue?.replace(/,/g,"").trim()
return _str?_str:str.innerText;
}
function splitauth(str,emblem){//存在作者-单位一对多,作者-单位多对一,需要拆分作者
let arr = [],_str = str.innerText?.split(emblem);
for(let i=0;i<_str.length;i++ ){
let obj = {
authorName: emblem==','?_str[i]?.trim():getName(str),
serial:emblem==','?1:Number(_str[i])//作者标记
}
arr.push(obj)
}
return arr
}
function unitElementsEnums(params) {//单位枚举
const arr = [];
for (let i = 0; i < params?.length; i++) {
let unit = params[i]?.nextSibling?.nodeValue?.replace(/;/g,"")?.trim();
let obj = {
unitName: unit?unit:params[i]?.innerText,
serial:i+1//单位标记
}
arr.push(obj)
}
return arr;
}
function combinationData() {//数据组合
const authors = isSignal(authorElements);//作者拆分后枚举
const units = unitElementsEnums(unitElements);//单位枚举
const newArrs = {
"articlesAuthors": []
};//新数据
for (let i = 0; i < authors.length; i++) {
let unitsName = '';
for (let j = 0; j < units.length; j++) {
if(authors[i].serial == units[j].serial){
unitsName = units[j].unitName;
break;
}
}
newArrs.articlesAuthors.push({
"authorName": authors[i].authorName,
"unitsName": unitsName
})
}
return newArrs;
}
const _texts = {"data":combinationData()};
if(_texts?.data?.articlesAuthors?.length){
GM_setClipboard(JSON.stringify(_texts), 'text');
alert('作者单位数据处理成功,已复制')
}else{
alert('操作失败,请检查是否有原始数据')
}
console.log(_texts)
}
}
//实例化插件
const _initMethods = new InitMethods();
//初始插件按钮相关
_initMethods.setCssDom_Fn();
//复制目录
$('.cjwk_copy_btn_men').click(function(){
_initMethods.getDirectoryData();
})
//复制原始图文数据
$('.cjwk_copy_btn_img').click(function(){
_initMethods.getBasicData();
})
//复制参考文献
$('.cjwk_copy_btn_cat').click(function(){
_initMethods.getLiteratureData();
})
//复制参考作者单位
$('.cjwk_copy_btn_authorsUnit').click(function(){
_initMethods.parseArticlesAuthorsUnit();
})
console.error('---------- 请给我们这些普通程序员多一点鼓励 ----------')
})();