网盘自动填写密码【威力加强版】

网盘自动填写提取密码【增强版】的基础上增加信息提取及保存功能。

As of 2017-08-27. See the latest version.

// ==UserScript==
// @name 			网盘自动填写密码【威力加强版】
// @description		网盘自动填写提取密码【增强版】的基础上增加信息提取及保存功能。
// @author			极品小猫
// @namespace   	https://greasyfork.org/zh-CN/users/3128
// @version			3.1.5
// @date			2015.10.30
// @modified		2017.07.19
// 
// 支持的网盘
// @include			http://pan.baidu.com/s/*
// @include			http://eyun.baidu.com/s/*
// @include     	http://*
// @include			https://*
// 
// 白名单
// @exclude			http*://*.pcs.baidu.com/*
// @exclude			http*://*.baidupcs.com/*
// @exclude			http*://*:8666/file/*
// @exclude			http*://*.baidu.com/file/*
// @exclude			http*://index.baidu.com/*
// 
// @exclude			http*://*.gov/*
// @exclude			http*://*.gov.cn/*
// @exclude			http*://*.taobao.com/*
// @exclude			http*://*.tmall.com/*
// @exclude			http*://*.alimama.com/*
// @exclude			http*://*.jd.com/*
// @exclude			http://*.ctrip.com/*
// @exclude			https://*.evernote.com/*
// @exclude			https://*.yinxiang.com/*
// @exclude			/^https?://(localhost|10\.|192\.|127\.)/
// @exclude			/https?://www.baidu.com/(?:s|baidu)\?/
// @exclude			http*://www.zhihu.com/question/*/answers/created
// require			http://code.jquery.com/jquery-2.1.4.min.js
// @require			http://cdn.staticfile.org/jquery/2.1.4/jquery.min.js
// @supportURL		https://greasyfork.org/zh-CN/scripts/29762/feedback
// @icon			https://eyun.baidu.com/box-static/page-common/images/favicon.ico
// @grant			unsafeWindow
// @grant        	GM_setValue
// @grant        	GM_getValue
// @grant			GM_listValues
// @grant			GM_xmlhttpRequest
// @grant			GM_registerMenuCommand
// @encoding		utf-8
// @run-at			document-idle
// ==/UserScript==

var urls=location.href;
var hash=location.hash;
var host=location.hostname.replace(/^www\./i,'').toLowerCase();
var paths=location.pathname.toLowerCase();

//功能开关 & 设置
var StorageSave=true;			//信息记录功能, localStorage 记录密码开关,true 为启用,false 为关闭
//-----------------------------建议开启,该功能可在再次打开没有密码融合的网盘链接时,从记录中读取“提取码”,从而让你在无法找回提取码时访问网盘

var StorageExp=7;				// localStorage 记录密码的有效期
var newTag=true;				// 网盘链接添加以新页面打开属性
unsafeWindow.eve = Event;
//GM_listValues();
/*
 * 更新日志
 * 3.1.5
 * 1、【修正】关闭信息记录时,仍然会显示记录的信息
 * 2、【修正】关闭信息记录时,提取码无法自动提交的问题
 * 3.1.4
 * 1、【修正】reimu.net 特殊融合兼容性问题
 * 2、【修正】不兼容中文提取码自动填写
 * 3、【修正】信息记录没有提取码的问题
 * 
 * 3.1.3.1
 * 1、【删除】shaoit.com 密码融合处理规则
 * 
 * 3.1.3
 * 1、【增强】度盘在点击时设置为新页面打开(可开关),参数变量为 newTag
 * 2、【修正】表格中提取密码为下一行表格的BUG
 * 3、【修正】gov.cn、gov的域名默认为白名单
 * 
 * 3.1.2
 * 1、【增强】解压密码提取,增加“压缩密码”关键字
 * 2、【修正】pan.baidu.com 解压密码获取错误
 * 3、【修正】Firefox 浏览器 GM插件 的兼容性问题
 * 4、【修正】其它小BUG
 * 
 * 3.1.1.1
 * 1、特殊支持网站,增加 小众软件论坛
 * 
 * 3.1.1
 * 1、修正解压密码内容处理导致提取码提取失效BUG
 * 2、修正网盘信息显示BUG
 *
 * 3.1.0
 * 1、增强提取码匹配规则,提高匹配成功率
 * 2、localStorage 信息记录 传递方式改为使用 GM_setValue、GM_getValue API
 * 3、无提取码,但有解压密码,也将进行信息记录
 * 
 * 3.0.0 (内部测试)
 * 1、使用 localStorage 记录密码等信息,默认记录 7 天
 * 2、增强“解压密码”提取规则
 * 3、打开已记录网盘时,若URL中无提取码,可从记录中读取提取码
 * 
 * 2.5.2.3
 * 1、MAD素材库(madsck.com)密码融合特殊支持
 * 2、修复 huhupan.com 的密码融合支持
 *
 * 2.5.2.2 - 未删除
 * 1、删除知乎跳转链处理代码
 * 
 * 2.5.3
 * 1、次元轨迹(acg44.com)密码融合处理
 * 2、修正“解压密码”的误识别
 * 3、Cookie 记录密码,保存7天
 * 
 * 2.5.2.1
 * 1、讯影网(xunyingwang.com)密码融合处理
 * 2、户户盘(huhupan.com)密码融合处理
 * 
 * 2.5.1
 * 1、殁漂遥(shaoit.com)密码融合处理改进
 * 
 * 2.5.0
 * 1、提升密码融合能力
 * 
 * 2.4.2 【2016.10.05】
 * 1、殁漂遥(shaoit.com)密码融合处理
 * 2、reimu.net 密码融合处理
 * 3、修复“跳转链处理”影响百度企业盘无法访问问题
 * 
 * 2.4.1.2 【2016.09.28】
 * 1、增加 sijihuisuo.club 的跳转链处理
 * 2、增加本地IP白名单
 * 
 * 2.4.1.1 【2016.09.21】
 * 1、增加携程网白名单
 * 
 * 2.4.1 【2016.09.21】
 * 1、支持一些特殊网站的密码融合预处理
 * 2、支持百度企业云的密码自动提交(企业盘的密码为4~14位)
 * 3、支持 www.0dayku.com 的提取码关键字“Extracted-code”
 * 
 * 2.3.3 【2016.08.08】
 * 1、知乎跳转链预处理
 * 
 * 2.3.2 【2016.08.04】
 * 1、恢复提取码中的“密码”关键字(适用于:心海e站)
 * 
 * 2.3.1 【2016.08.03】
 * 1、增加微云网盘提取码支持(匹配规则来自原作者 Jixun.Moe)
 * 2、修正提取码兼容问题
 * 3、修正重复添加提取码
 * 
 * 2.3.0 【2016.08.01】
 * 1、移除对金山快盘、新浪云盘的支持
 * 2、百度企业云盘不追加验证码
 * 3、受贴吧页面跳转影响,暂时不支持贴吧的密码提取,已将贴吧加入白名单
 * 4、提升链接&密码融合的成功率	—— A 标签绑定函数更改为 body 点击事件监听(根据原作者 Jixun.Moe 的建议)
 * 5、找不到密码时的遍历方式更改(感谢 10139 - mudoo 的建议)
 * 6、支持密码放在换行表格中的提取
*/

var site = {
  'YunDisk':{
    'pan.baidu.com':{
      ShareID : getQueryString('shareid'),
      chk:	/^[a-z0-9]{4}$/,
      code:	'#accessCode',
      btn:	'#submitBtn,#getfileBtn',
      PreProcess: function() {	//已处理
        if(StorageSave){
          if(GM_getValue('CatPW')=='undefined') GM_setValue('CatPW',{});	//初始化
          //window.history.pushState('state', 'title', hash.replace(/#list\/path=.+/i,'#'));

          var CatPW, yunData=unsafeWindow.yunData;
          if(!localStorage[yunData.SHARE_ID]){
            CatPW=GM_getValue('CatPW');
            CatPW.ShareUK=yunData.SHARE_UK||getQueryString('uk');			//获取 分享用户ID
            CatPW.ShareID=yunData.SHARE_ID||getQueryString('shareid');		//获取 分享文件ID
            var Qstr=CatPW.ShareStr=/Src=/i.test(hash)?hash:location.search;				//网址参数提取
          } else {
            CatPW=StorageDB(yunData.SHARE_ID||getQueryString('shareid')).read();
          }

          //提交密码前
          CatPW.sCode=StorageDB(CatPW.ShareID).find('sCode')||(GM_getValue('CatPW').Hash?GM_getValue('CatPW').Hash.replace('#',''):/^#/.test(hash)&&!/^#list\/path=/.test(hash)?hash.match(/^#([^&]+)&?/)[1]:'');		//获取 提取码
          CatPW.webSrc=decodeURIComponent(getQueryString('webSrc',Qstr)||StorageDB(CatPW.ShareID).find('webSrc')||GM_getValue('CatPW').webSrc);
          CatPW.unPW=decodeURIComponent(getQueryString('unPW',Qstr)||(StorageDB(CatPW.ShareID).find('unPW')?StorageDB(CatPW.ShareID).find('unPW'):(GM_getValue('CatPW').unPW?GM_getValue('CatPW').unPW:''))); CatPW.webTitle=decodeURIComponent(getQueryString('webTitle',Qstr)||StorageDB(CatPW.ShareID).find('webTitle')||GM_getValue('CatPW').webTitle);
          CatPW.date=Dates();
          console.log(conf,CatPW);

          $(conf.btn).click(function(){	//提交密码时
            if(StorageSave)  {
              CatPW.sCode=!CatPW.sCode?$(CatPW.code).val().trim()!=''?$(CatPW.code).val().trim():CatPW.sCode:CatPW.sCode;		//如果 localStorage 没有密码,则重新手动记录
            }

            if(!localStorage[CatPW.ShareID]&&(CatPW.sCode&&($('#tip').css('display')=='none')||$('#tip').text()=='')) {
              //如果不存在记录时,且没有任何提示信息时
              StorageDB(CatPW.ShareID).insert(CatPW);
              StorageDB('ShareIDexp').add(CatPW.ShareID,{'date':Dates(),'id':CatPW.ShareID,'exp':$.now()+StorageExp*24*60*60*1000});		//记录超时时间
            } else if(CatPW.sCode&&$('#tip').css('display')=='none'){
              StorageDB('ShareIDexp').add(CatPW.ShareID,{'date':Dates(),'id':CatPW.ShareID,'exp':$.now()+StorageExp*24*60*60*1000});		//记录超时时间
            } else if($('#tip').text()=='密码错误'){
              delete localStorage[CatPW.ShareID];
              StorageDB('ShareIDexp').delete(CatPW.ShareID);		//删除超时时间记录
            }
          });
          if(CatPW.unPW&&!localStorage[CatPW.ShareID]){
            StorageDB(CatPW.ShareID).insert(CatPW);
            StorageDB('ShareIDexp').add(CatPW.ShareID,{'date':Dates(),'id':CatPW.ShareID,'exp':$.now()+StorageExp*24*60*60*1000});		//记录超时时间
          }

          //显示记录的信息
          if(localStorage[CatPW.ShareID]){
            $('<DIV>').attr('id','CatPW').css({'font-size':'14px'}).text('提取码:'+CatPW.sCode+'  '+'解压密码:').insertBefore($('.module-share-header'));
            //解压密码
            $('<input>').attr({'id':'unPW','title':'点击复制密码'}).css({'margin':'0 10px','width':'100px','text-align':'center'}).val(CatPW.unPW).click(function(){
              document.execCommand("SelectAll");document.execCommand("copy");
            }).appendTo($('#CatPW'));
            //来源页面:
            $('<A>').attr({'id':'CatPWsrc','href':CatPW.webSrc,'target':'blank'}).text('网盘来源:'+CatPW.webSrc).appendTo($('#CatPW'));
            $('<button>').text('删除记录').val('删除记录').click(function(){
              delete localStorage[CatPW.ShareID];
              this.disabled=true;
            }).appendTo($('#CatPW'));
          }

          StorageDB('ShareIDexp').deleteExpires();

        }
      }
    },
    'eyun.baidu.com': {
      chk:	/^[a-z0-9]{4}$/,
      code:	'.share-access-code',
      btn:	'.g-button-right',
      PreProcess: function() {
        if((hash&&!/sharelink|path/i.test(hash))&&!/enterprise/.test(paths)) {
          location.href=location.href.replace(location.hash,'');
        }
        conf.ShareUK=yunData.SHARE_UK||getQueryString('uk');		//获取 分享用户ID
        conf.ShareID=yunData.SHARE_ID||getQueryString('cid');		//获取 分享文件ID
        conf.sCode=/^#/.test(hash)?hash.match(/^#(\w+)&?/)[1]:StorageDB(conf.ShareID).find('sCode');		//获取 提取码
        $(conf.btn).click(function(){
          if(!localStorage[conf.ShareID]&&conf.sCode) {
            StorageDB(conf.ShareID).insert({'sCode':conf.sCode});
            StorageDB('ShareIDexp').add(conf.ShareID,{'id':conf.ShareID,'exp':$.now()+StorageExp*24*60*60*1000});		//记录超时时间
          }
        });
        StorageDB('ShareIDexp').deleteExpires();
      }
    },
    'weiyun.com': {
      chk: /^[a-z0-9]{4}$/i,
      code: '#outlink_pwd',
      btn:  '#outlink_pwd_ok'
    },
  },
  'pwdRule' : /(?:提取|访问)[码碼]?\s*[:: ]?\s*([a-z\d]{4})/,			//常规密码
  'codeRule' : /(?:(?:提取|访问|密[码碼]|艾|Extracted-code)[码碼]?)\s*[:: ]?\s*([a-z\d]{4})/i,	//其它类型的密码
  //跳转链预处理
  'JumpUrl' : {
    'zhihu.com' :  {
      href: $('A[href*="//link.zhihu.com/?target="]'),
      url:/.*\/\/link\.zhihu\.com\/\?target=/
    },
    'sijihuisuo.club': {
      href: $('.down-tip A[href^="https://www.sijihuisuo.club/go/?url="]'),
      url: 'https://www.sijihuisuo.club/go/?url='
    }
  },
  //密码融合需要特殊支持的网站
  'Support' : {
    'dakashangche.com':{
      path:/\/sj\/\d/,
      callback:function(){
        console.log('特殊支持');
        $('.down-tip>a[href*="du.acgget.com"]').each(function(){
          DownAjax(this.href,'.panel-body',function(e){
            console.log('return',e);
            $(e).appendTo($('#paydown'));
          });
        })
      }
    },
    'meta.appinn.com':{
      path:/\/t\/[^/]+\//i,
      callback:function(){
        new PreHandle.VM();
        $('A[href*="pan.baidu.com"],A[href*="eyun.baidu.com"]').each(function(){
          $(this).data({'url':this.href}).click(function(e){
            location.href=$(this).data('url');
          });
        });
      }
    },
    'madsck.com':{
      path: /\/resource\/\d+/,
      callback:function(){
        var ID=$('.btn-download').data('id');
        $.ajax({
          "url":"http://www.madsck.com/ajax/login/download-link?id="+ID,
          method: "GET",
          dataType: "json",
          success:function(e){
            var res=e.resource;
            $('.btn-download').css('display','none');
            $('<a>').attr({'href':res.resource_link+'#'+res.fetch_code,'target':'blank','class':'btn-download'}).css({'line-height':'60px','text-align':'center','font-size':'24px'}).text('下载').insertBefore('.btn-download');
          }
        });
      }
    },
    'idanmu.co': {
      path : /storage\-download/i,
      callback : function(){
        $('.input-group').each(function(){
          $(this).text($(this).text()+$(this).find('input').val());
        });
      }
    },
    'a.acgluna.com':{
      
    },
    'acg44.com':{
      //search:['page_id','p'],
      path:/download/i,
      callback : function(){
        site['codeRule']=/(?:(?:提取|访问|密[码碼])[码碼]?)\s*[:: ]?\s*([a-z\d]{4}|[^$]+)/i
        addMutationObserver('#download-container',function(e){
          e.some(function(a){
            for(var i in a.addedNodes){
              var b=a.addedNodes[i];
              if(b.className=='animated fadeIn') {
                var VerCode=$('[id^="downloadPwd"]').val();
                var unZipPW=encodeURIComponent($('[id^="extractPwd"]').val());
                var DownUrl=$('#download-container a.btn').attr('href');
                if(/pan.baidu.com\/share/i.test(DownUrl)){
                  $('#download-container a.btn').attr('href',DownUrl+'&unPW='+unZipPW+'&Src='+encodeURIComponent(urls));
                } else {
                  $('#download-container a.btn').attr('href',DownUrl+'#'+VerCode+'&unPW='+unZipPW+'&Src='+encodeURIComponent(urls));
                }
              }
            }
          });
        });
      }
    },
    'xunyingwang.com':{
      path:/movie/i,
      callback:function(){
        $(window).load(function(){
          $('A[href*="pan.baidu.com"],A[href*="eyun.baidu.com"]').each(function(){
            $(this).attr('href',$(this).attr('href')+'#'+$(this).next("strong").text());
          });
        });
      }
    },
    'huhupan.com':{
      path:/e\/extend\/down/i,
      callback:function(){
        var _Linktmp=$('A[href*="pan.baidu.com"],A[href*="eyun.baidu.com"]');
        var _PWtmp=$('input[id^="bdypas"],input[id^="foo"]');
        for(i=0;i<_Linktmp.length;i++){
          _Linktmp[i].href+="#"+_PWtmp[i].value;
        }
      }
    },
    'blog.reimu.net': {
      path: /archives/i,
      callback: function(){
        site['codeRule']=/(?:(?:提取|访问|密[码碼])[码碼]?)\s*[:: ]?\s*([a-z\d]{4}|8酱)/i;
        console.log(site['codeRule']);
      }
    },
    'reimu.net': {
      path: /archives/i,
      callback: function(){
        site['codeRule']=/(?:(?:提取|访问|密[码碼])[码碼]?)\s*[:: ]?\s*([a-z\d]{4}|8酱)/i;
        console.log(site['codeRule']);
      }
    }
  }
};

var conf = site['YunDisk'][host];											//设置主域名

/* -----===== 生成正则,校验匹配的网盘 Start =====----- */
var HostArr = [];									//生成域名数组
for(var i in site['YunDisk']) HostArr.push(i);					//插入域名对象数组
var HostExp = new RegExp(HostArr.join("|"),'i');	//生成支持网盘的校验的正则

/* -----===== 生成正则,校验匹配的网盘 End =====----- */

/* -----===== 检查是否需要处理跳转链 Start =====----- */

//console.log(site.JumpUrl[host]);
if(site['JumpUrl'][host]){
  console.log(site['JumpUrl'][host]['href']);
  site['JumpUrl'][host]['href'].each(function(){
    console.log(site['JumpUrl'][host]['rep'])
    $(this).attr({'href':decodeURIComponent($(this).attr('href').replace(site['JumpUrl'][host]['url'],'')),'target':'blank'});
  });
}
/* -----===== 检查是否需要处理跳转链 End =====----- */


if(conf&&!/zhidao.baidu.com/i.test(host)){	//网盘页面填密码登录
  // 抓取提取码
  if(conf.PreProcess) conf.PreProcess();		//内容预处理
  //var sCode = hash.slice(1).trim();				//提取码获取
  var sCode =/^#/.test(hash)?hash.match(/^#([^&]+)&?/)[1]:StorageDB(conf.ShareID).find('sCode');		//获取 提取码
  // 调试用,检查是否为合法格式

  if (!sCode) {
    console.log('没有 Key 或格式不对');
  } else {
    console.log ('抓取到的提取码: %s', sCode);
  }

  // 加个小延时
  setTimeout (function () {
    // 键入提取码并单击「提交」按钮,报错不用理。
    var codeBox = $(conf.code),
        btnOk = $(conf.btn);
    if(codeBox.length>0) {		//存在密码框时才进行密码提交操作
      codeBox.val(sCode);		//填写验证码
      if (conf.preSubmit)
        if (conf.preSubmit (codeBox, btnOk))
          return ;
      btnOk.click();
    }
  }, 10);

} else {
  var PreHandle={	//内容预处理
    Text : function(text){	//预处理含解码密码的文本
      text=text?typeof(text)=="string"?text.trim():text.textContent.trim():null;
      text=text?text.replace(/([\[【]?解[压壓]|[压壓][缩縮])密[码碼][\]】]?\s*[:: ]?\s*([a-z\d]{4}|[^\n]+)/ig,''):null;
      return text;
    },
    Code : function(obj){	//
      var text=this.Text(obj);
      if(!text) return;
      //首先尝试使用 提取码|访问码 作为密码匹配的关键字,无效时则使用模糊匹配规则
      var pw=site['pwdRule'].test(text)?text.match(site['pwdRule'])[1]:site['codeRule'].test(text)?text.match(site['codeRule'])[1]:null;
      //console.log(text,pw);
      return pw;
    },
    VM : function(){	//暴力匹配
      var Link=$('A[href*="pan.baidu.com"],A[href*="eyun.baidu.com"]');

      for(i=0;i<Link.length;i++){
        var LinkParent=$(Link[i]).parent();
        var LinkParentHtml=LinkParent.html();
        if(PreHandle.Code(LinkParentHtml)) Link[i].href+='#'+PreHandle.Code(LinkParentHtml);
      }
    }
  }

  //密码融合 特别支持的网站
  var SupportHost=site['Support'][host];
  if(SupportHost&&(SupportHost['path']?SupportHost['path'].test(paths):getQueryString(SupportHost['search']))) {
    SupportHost.callback();
  }
  //监听 A 标签点击事件
  $('body').on('click', 'a', function (e) {
    var target=this, CatPW;
    
    //如果目标对象为百度企业盘,提升密码匹配范围,以兼容百度企业云
    if(/eyun.baidu.com/i.test(this.href)) {
      site['pwdRule']=/(?:提取|访问)[码碼]?\s*[:: ]?\s*([a-z\d]{4,14})/;
      site['codeRule']=/(?:(?:提取|访问|密[码碼]|Extracted-code)[码碼]?)\s*[:: ]?\s*([a-z\d]{4,14})/i;
    }

    //正则校验超链接匹配的网盘
    //console.log('处理好的文本:'+PreHandle.Text(target.nextSibling));
    //console.log('Code匹配结果',PreHandle.Code(target.parentNode.nextSibling));

    if(HostExp.test(this.href)){
      if(newTag) this.target='blank';		//新页面打开网盘
      
      //初始化信息记录变量
      CatPW={'Src':this.href,'Hash':this.hash,"webSrc":encodeURIComponent(urls),"webTitle":encodeURIComponent(document.title)};
      
      
      if(this.hash) return;		//如果超链接已有 hash 则跳过
      console.group('网盘自动填写密码');
      if(PreHandle.Code(target)){
        console.log('在当前超链接的对象中查找密码');
        target.href+='#'+PreHandle.Code(target);
      } else if(PreHandle.Code(target.nextSibling)){
        console.log('密码在超链接后面的兄弟元素中');
        target.href+='#'+PreHandle.Code(target.nextSibling);
      } else if(PreHandle.Code(target.parentNode)){
        console.log('从父对象中查找密码');
        target.href+='#'+PreHandle.Code(target.parentNode);
      } else {
        var i = 0,
            maxParent = 5,	//向上遍历的层级
            parent = target;
        while(i<maxParent) {
          i++;									//遍历计数
          parent = parent.parentNode;			//取得父对象
          console.log('遍历上级目录查找密码:'+ i,parent);
          if(parent.tagName=="TR") {				//如果父对象是表格,则从表格中提取密码
            if(PreHandle.Code(parent.nextElementSibling)) {
              parent=parent.nextElementSibling;
              console.log('表格中查找密码成功!',parent);
              target.href+='#'+PreHandle.Code(parent);
              break;
            }
          } else if(PreHandle.Code(parent.nextSibling)){
            console.log('向上遍历查找,在超链接后面的兄弟元素中,',parent.nextSibling);
            target.href+='#'+PreHandle.Code(parent.nextSibling);
            break;
          } else if(PreHandle.Code(parent)) {		//否则按照常规方式提取密码
            console.log('向上遍历查找密码成功!');
            target.href+='#'+PreHandle.Code(parent);
            break;
          } else {
            if(maxParent>5) console.log('已超出遍历范围');
          }
          if(parent==document.body) break;								//如果已经遍历到最顶部
        }
      }
      if(this.hash) CatPW.Hash=this.hash;

      if(StorageSave) {
        var unPWArr=[
          /password[:: ]?([^\n]+)/igm,
          /解压[:: ]?(\w+)/gm,
          /【解压密码】\s*[:: ]?\s*([^\n]+)/igm,
          /\[解压密码\]\s*[:: ]?\s*([a-z\d\.:/]+)/igm,		//http://www.itokoo.com/
          /(?:解[压壓]密?[码碼])\s*[:: ]?\s*([a-z\d\.:/]+)/igm,
          /(?:解[压壓]密?[码碼])(?:都?是)?\s*[:: ]?\s*([^\w]+)[^$\r\n]/igm,
          /【?压缩密码】?\s*[:: ]?\s*([^\n]+)/igm
        ]
        for(i=0;i<unPWArr.length;i++) {
          var unPWTemp=unPWArr[i].exec(document.body.textContent);
          if(unPWTemp) {
            //console.log('解压密码提取:',unPWTemp,encodeURIComponent(unPWTemp[1]));
            CatPW.unPW=encodeURIComponent(unPWTemp[1]);
            break;
          }
        }
        GM_setValue('CatPW',CatPW);
        console.log(GM_getValue('CatPW'));
      }
    }
    console.groupEnd();
  });
}

function addMutationObserver(selector, callback, Kill) {
  var watch = document.querySelector(selector);
  //console.log(watch);

  if (!watch) {
    return;
  }
  var observer = new MutationObserver(function(mutations){
    //console.log(mutations);
    var nodeAdded = mutations.some(function(x){ return x.addedNodes.length > 0; });
    if (nodeAdded) {
      callback(mutations);
      if(Kill) console.log('停止'+selector+'的监控'),observer.disconnect();
    }
  });
  observer.observe(watch, {childList: true, subtree: true});
}

function getQueryString(name,url) {//筛选参数
  url=url?url.match(/[?#].*/).toString():location.search;	//网址传递的参数提取,如果传入了url参数则使用传入的参数,否则使用当前页面的网址参数

  if(Array.isArray(name)){
    for(var i in name){
      var reg = new RegExp("(?:^|&)(" + name[i] + ")=([^&]*)(?:&|$)", "i");		//正则筛选参数
      var str = url.substr(1).match(reg);
      if (str !== null) return unescape(str[2]);
    }
  } else {
    var reg = new RegExp("(?:^|&)(" + name + ")=([^&]*)(?:&|$)", "i");		//正则筛选参数
    var str = url.substr(1).match(reg);
    if (str !== null) return unescape(str[2]);
  }
  return null;
}

function StorageDB(collectionName) {
  //如果没有 集合名,则使用默认 default
  collectionName = collectionName ? collectionName : 'default';
  //创建JSON缓存,如果缓存存在,则转为JSON,否则新建
  var cache = localStorage[collectionName] ? JSON.parse(localStorage[collectionName]) : {};

  return {
    add : function(name, value) {
      cache[name]=value;
      localStorage.setItem(collectionName, JSON.stringify(cache));        //回写 localStorage
    },
    del:function(name) {
      if(name) {
        delete cache[name];
        localStorage.setItem(collectionName, JSON.stringify(cache));        //回写 localStorage
      } else {
        //删除整个 localStorage 数据
        localStorage.removeItem(name);
      }
    },
    insert: function(obj){
      localStorage.setItem(collectionName, JSON.stringify(obj));
    },
    Updata : function(name,obj,value){
      cache[obj]=cache[obj]||{};
      cache[obj][name]=value;
      localStorage.setItem(collectionName, JSON.stringify(cache));        //回写 localStorage
    },
    Query : function(obj,name){
      return cache[obj]?name?(cache[obj][name]?cache[obj][name]:null):cache[obj]:null;
    },
    find : function(name) {
      return cache[name];
    },
    read : function(){
      return cache;
    },
    deleteExpires : function(now){
      var now=now||$.now();
      for(var i in cache) {
        //console.log(i,collectionName,now,cache[i]['exp'],now>cache[i]['exp']/*,cache[i],localStorage[i]*/); //删除记录显示
        if(now>cache[i]['exp']) {
          //delete cache[i];
          //console.log('删除:',i,cache,cache[i]); //确定需要删除的内容
          //localStorage.setItem(collectionName, JSON.stringify(cache));		//删除延时记录
          //localStorage.removeItem(i);										//删除 localStorage 记录
        }
      }
    }
  }
}

function DownAjax(urls,selection,callback){
  GM_xmlhttpRequest({
    method: "GET",
    url: urls,
    onload: function (result) {
      var parsetext = function(text){
        var doc = null;
        try {
          doc = document.implementation.createHTMLDocument("");
          doc.documentElement.innerHTML = text;
          return doc;
        }
        catch (e) {
          alert("parse error");
        }
      }
      var Down;
      var doc = parsetext(result.responseText);
      console.log(doc,$(doc));
      var t = $(doc).find(selection);
      callback(t);
    }
  });
}

function Dates(){
  var sDate=new Date();
  return sDate.getFullYear()+'/'+(sDate.getMonth()+1)+'/'+sDate.getDate();
}