百度 时光机

随意跳转百度不同时间搜索结果

  1. // ==UserScript==
  2. // @name 百度 时光机
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.3
  5. // @description 随意跳转百度不同时间搜索结果
  6. // @author hzhbest
  7. // @match https://www.baidu.com/s?*
  8. // @match https://www.baidu.com/baidu?*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=baidu.com
  10. // @grant none
  11. // @license GNU GPLv3
  12. // ==/UserScript==
  13.  
  14. //1.0 + 增加“baidu?”适配
  15.  
  16. (function() {
  17. 'use strict';
  18.  
  19. // 根据 location.href 识别日期区间搜索行为
  20. // https://www.baidu.com/s?wd=GDFDA&gpc=stf%3D1577808000%2C1610035200%7Cstftype%3D2
  21. // 其中,“wd=”后面是关键词,“gpc=”后面是结果过滤,“stf%3D……%2C……%7Cstftype%3D2”是日期区间的标识
  22. // 识别搜索关键词 kw 和日期区间始末点 qiri 和 vsri(单位秒,转换前要先转成毫秒)
  23. // 构建时光机框【divMain【labelTitle】【labelStart】【inputStart】【labelEnd】【inputEnd】【divBtnGo】】
  24. // 转换 qiri 和 vsri 为日期格式(yyyy-m-d)文本 qistr 和 vsstr 并放入 inputStart 和 inputEnd 中
  25. // 点 divBtnGo 时,补全两 input* 中的 *str 为日期格式,并转换为日期数 *ri,与 kw 重组新网址,并当前页面加载
  26.  
  27. //const d0 = Date.parse('1970-1-1');
  28. const msxd = 24 * 60 * 60 * 1000;
  29. const units = ['天', '周', '月', '年'];
  30. let divMain = document.body.appendChild(document.createElement('div'));
  31. divMain.id = 'TM_Main';
  32. setTimeout(init,2000);
  33.  
  34. let csstxt = `
  35. .TM_Main {position: fixed; top: 100px; left: 0px; z-index: 100000; background: #fff;
  36. padding: 4px; border: 1px solid #ddd; font-size: 14pt; width: 115px; overflow: hidden;
  37. transition: width 0.2s linear 3s;}
  38. .TM_Main:hover {width: 190px; transition: width 0.2s linear 0s; box-shadow: 0 1px 12px 4px #ccc;}
  39. .TM_Title {font-size: 15pt; font-weight: bold;}
  40. .TM_Label {overflow: hidden; white-space: nowrap; display: block; color: #969696; padding-top: 9px;}
  41. .TM_Input {width: 180px; font-size: larger; border-bottom: 1px solid #cecece;
  42. border-top: none; border-left: none; border-right: none; margin-bottom: 1px;}
  43. .TM_Input:hover {border-bottom: 2px solid #878787; margin-bottom: 0px;}
  44. .TM_ilbox {width: 185px; padding-top: 9px;}
  45. #TM_last, #TM_unit {display: inline;}
  46. #TM_last {width: 40px;}
  47. .TM_Main:hover #TM_last {width: 65px;}
  48. #TM_unit {width: 45px; margin-left: 5px; outline: none; background: transparent;
  49. border-bottom: 1px solid #cecece; border-top: none; border-left: none; border-right: none;}
  50. #TM_unit:hover {border-bottom: 2px solid #878787;}
  51. .TM_Button {margin:5px; padding: 0px 5px; width: 50px; height: 50px;
  52. cursor: default; position: absolute; left: 120px; bottom: 3px;
  53. text-align: center; background: #f5f5f5;}
  54. .TM_Button:hover {outline: 2px solid #99e; background: #eef; color: black;}
  55. .TM_Button:active {outline: 2px solid #22f; background: #cce;}
  56. `;
  57. addCSS(csstxt);
  58.  
  59.  
  60. function init(){
  61. let kw, qiri, vsri, arri;
  62. let lTitle, lKword, inKword, lLast, inLast, seUnit, lStart, lEnd, inStart, inEnd, divBtnGo;
  63.  
  64. lTitle = creaElemIn('label', divMain);
  65. lKword = creaElemIn('label', divMain);
  66. inKword = creaElemIn('input', divMain);
  67. let inlinebox = creaElemIn('div', divMain);
  68. lLast = creaElemIn('label', inlinebox);
  69. inLast = creaElemIn('input', inlinebox);
  70. seUnit = creaElemIn('select', inlinebox);
  71. units.forEach(unit => {
  72. let opUnit = creaElemIn('option', seUnit);
  73. opUnit.value = unit;
  74. opUnit.innerHTML = unit;
  75. });
  76. lStart = creaElemIn('label', divMain);
  77. inStart = creaElemIn('input', divMain);
  78. lEnd = creaElemIn('label', divMain);
  79. inEnd = creaElemIn('input', divMain);
  80. divBtnGo = creaElemIn('div', divMain);
  81.  
  82. lTitle.innerHTML = "百度时光机";
  83. lKword.innerHTML = "搜索关键词";
  84. lLast.innerHTML = "最近:";
  85. lStart.innerHTML = "开始日期";
  86. lEnd.innerHTML = "结束日期";
  87. divBtnGo.innerHTML = "立即穿梭";
  88. inKword.title = "在此输入关键词,跟随时光机穿梭!";
  89. inLast.title = "在此输入数字,可用鼠标滚轮增减";
  90. seUnit.title = "在此选择时间单位,可用鼠标滚轮切换";
  91. inStart.title = "开始日期,可只输年份或年月,可用鼠标滚轮增减月份";
  92. inEnd.title = "结束日期,可只输年份或年月,可用鼠标滚轮增减月份";
  93.  
  94. inKword.id = 'TM_kword';
  95. inStart.id = 'TM_start';
  96. inEnd.id = 'TM_end';
  97. inLast.id = 'TM_last';
  98. seUnit.id = 'TM_unit';
  99. divMain.className = 'TM_Main';
  100. lTitle.className = 'TM_Title';
  101. lKword.className = lStart.className = lEnd.className = 'TM_Label';
  102. lLast.className = 'TM_llast';
  103. inKword.className = inStart.className = inEnd.className = inLast.className = 'TM_Input';
  104. inlinebox.className = 'TM_ilbox';
  105. inLast.value = 1;
  106.  
  107. var wheelEvt = "onwheel" in document.createElement("div") ? "wheel" : (document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll"); //compatibility fix for Chrome-core browsers
  108. inLast.addEventListener(wheelEvt, changenumber);
  109. inLast.addEventListener('input', refreshLastdate);
  110. inLast.addEventListener('keypress', submit);
  111. seUnit.addEventListener(wheelEvt, changeunit);
  112. seUnit.addEventListener('change', refreshLastdate);
  113. inStart.addEventListener(wheelEvt, changemonth);
  114. inEnd.addEventListener(wheelEvt, changemonth);
  115. inStart.addEventListener('blur', checkdate);
  116. inEnd.addEventListener('blur', checkdate);
  117. inStart.addEventListener('keypress', submit);
  118. inEnd.addEventListener('keypress', submit);
  119. inKword.addEventListener('keypress', submit);
  120. divBtnGo.className = 'TM_Button';
  121. divBtnGo.addEventListener('click', go);
  122.  
  123. kw = getkw(location.href);
  124. inKword.value = decodeURI(kw);
  125.  
  126. arri = getds(location.href); //console.log(arri);
  127. qiri = arri[0];
  128. vsri = arri[1];
  129. let edate, sdate;
  130. if (qiri == 0 || vsri == 0) {
  131. edate = new Date();
  132. sdate = new Date(edate - 180 * msxd);
  133. } else {
  134. edate = numTOdate(vsri);
  135. sdate = numTOdate(qiri);
  136. }
  137. inEnd.value = edate.getFullYear() + "-" + (edate.getMonth() + 1) + "-" + edate.getDate();
  138. inStart.value = sdate.getFullYear() + "-" + (sdate.getMonth() + 1) + "-" + sdate.getDate();
  139. }
  140.  
  141. function go() { //点“穿梭”按钮后以时光机内的关键词和日期进行跳转(若关键词为空则使用当前关键词)
  142. let inS = document.querySelector('#TM_start');
  143. let inE = document.querySelector('#TM_end');
  144. let inK = document.querySelector('#TM_kword');
  145. let ednum, sdnum;
  146. ednum = dateTOnum(fulldate(inE.value,true));//console.log(ednum);
  147. sdnum = dateTOnum(fulldate(inS.value,false));//console.log(sdnum);
  148. let kw = inK.value || getkw(location.href);
  149. window.location.href = "https://www.baidu.com/s?wd=" + kw + "&gpc=stf%3D" + sdnum + "%2C" + ednum + "%7Cstftype%3D2&ie=utf-8";
  150. }
  151.  
  152. function changemonth(e){
  153. e.preventDefault();
  154. e.stopPropagation();
  155. let isend = (e.target.id == 'TM_end')? true : false;
  156. let cdate = new Date(fulldate(e.target.value, isend));
  157. let ddate = dateUnitConv(cdate, wheelToNum(e), "月");
  158. e.target.value = dateToStr(ddate);
  159. }
  160.  
  161. function changenumber(e) {
  162. e.preventDefault();
  163. e.stopPropagation();
  164. let c = parseInt(e.target.value);
  165. e.target.value = wheelToNum(e, c);
  166. refreshLastdate();
  167. }
  168.  
  169. function refreshLastdate() {
  170. let inS = document.querySelector('#TM_start');
  171. let inE = document.querySelector('#TM_end');
  172. let inL = document.querySelector('#TM_last');
  173. let seU = document.querySelector('#TM_unit');
  174. let cdate = new Date();
  175. inE.value = dateToStr(cdate);
  176. let ddate = dateUnitConv(cdate, -inL.value, seU.value);
  177. inS.value = dateToStr(ddate);
  178. }
  179.  
  180. function changeunit(e) {
  181. e.preventDefault();
  182. e.stopPropagation();
  183. let seU = e.target;
  184. let c = seU.selectedIndex;
  185. c = wheelToNum(e, c);
  186. if (c>=seU.options.length) {
  187. c = 0;
  188. } else if (c<0) {
  189. c = seU.options.length - 1;
  190. }
  191. seU.selectedIndex = c;
  192. refreshLastdate();
  193. }
  194.  
  195. function checkdate(e) {
  196. let t = e.target;
  197. let d = fulldate(t.value, t.id == "TM_end");
  198. t.value = dateToStr(d);
  199. }
  200.  
  201. function submit(e) {
  202. if (e.which == 10 || e.which == 13) {
  203. go();
  204. }
  205. }
  206.  
  207. // https://www.baidu.com/s?wd=GDFDA&gpc=stf%3D1577808000%2C1610035200%7Cstftype%3D2
  208. function getkw(url) { //从url中提取关键词
  209. let exp = /(?<=wd\=)[^&]+(?=&?)/i;
  210. return exp.exec(url)[0].replace("+", " ");
  211. }
  212.  
  213. function getds(url) { //从url中提取日期数数组[qiri,vsri]
  214. let exp = /(?<=gpc\=stf\%3D)[\d\%C]+(?=\%7Cstftype\%3D2)/i;
  215. let ds = exp.exec(url); console.log(ds);
  216. if (!!ds) {
  217. let outs = ds[0]; //正则匹配出的是结果的“数组”,因此第一匹配结果需要是数组index 0的元素
  218. return outs.replace('%2C', '_').split("_");
  219. } else {
  220. return "0_0".split("_");
  221. }
  222. }
  223.  
  224.  
  225. function wheelToNum(e, initval) {
  226. console.log(e.deltaY);
  227. let v = initval || 0;
  228. return ((e.deltaY > 0) ? 1 : -1) + v;
  229. }
  230.  
  231. function dateUnitConv(sdate, num, unit) {
  232. let y = sdate.getFullYear(), m = sdate.getMonth(), d = sdate.getDate();
  233. switch (unit) {
  234. case "天":
  235. return new Date(y, m, d + num);
  236. case "周":
  237. return new Date(y, m, d + num * 7);
  238. case "月":
  239. return new Date(y, m + num, d);
  240. case "年":
  241. return new Date(y + num, m, d);
  242. }
  243. }
  244.  
  245. function dateToStr(ddate) {
  246. return ddate.getFullYear() + "-" + (ddate.getMonth() + 1) + "-" + ddate.getDate();
  247. }
  248.  
  249. function fulldate(str, isend){ //将文本补全为“yyyy-m-d”格式,并输出日期,其中要补全的文本必须有四位年,可缺日或缺月日,即“yyyy”、“yyyy-m”格式
  250. let odate,oy,om,od;
  251. let ard = str.split('-');
  252. if (ard.length == 1){ // 只有年的话,非结尾则输出1月1日,结尾输出12月31日
  253. om = (isend)? 11 : 0;
  254. od = (isend)? 31 : 1;
  255. odate = new Date(parseInt(str), om, od);
  256. } else if (ard.length == 2){ // 只有年月的话,非结尾输出当月1日,结尾输出当月末日(下月0日)
  257. oy = parseInt(ard[0]);
  258. om = parseInt(ard[1]) - 1;
  259. odate = (isend)? new Date(oy,om + 1, 0) : new Date(oy, om, 1);
  260. } else {
  261. odate = Date.parse(str) // 年月日皆有则直接输出
  262. }
  263. return odate;
  264. }
  265.  
  266. function dateTOnum(odate){ //日期转换成秒数
  267. return odate / 1000;
  268. }
  269.  
  270. function numTOdate(onum){ //日数转换为日期对象
  271. return new Date(onum * 1000);
  272. }
  273.  
  274. function creaElemIn(tagname, destin) {
  275. let theElem = destin.appendChild(document.createElement(tagname));
  276. return theElem;
  277. }
  278.  
  279. function addCSS(css) {
  280. let stylenode = creaElemIn('style',document.getElementsByTagName('head')[0]);
  281. stylenode.textContent = css;
  282. stylenode.type = 'text/css';
  283. stylenode.id = 'ali_c_toc';
  284. }
  285.  
  286.  
  287.  
  288.  
  289. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址