Greasy Fork is available in English.

百度指数

百度指数爬虫工具

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
  1. // ==UserScript==
  2. // @name 百度指数
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description 百度指数爬虫工具
  6. // @author siji-Xian
  7. // @match *://index.baidu.com/v2/main/index.html*
  8. // @icon https://www.google.com/s2/favicons?domain=oceanengine.com
  9. // @grant none
  10. // @license MIT
  11. // @require https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.2.1/jquery.min.js
  12. // @require https://cdn.bootcss.com/moment.js/2.20.1/moment.min.js
  13. // @require https://greatest.deepsurf.us/scripts/404478-jsonexportexcel-min/code/JsonExportExcelmin.js?version=811266
  14. // @require https://greatest.deepsurf.us/scripts/455576-qmsg/code/Qmsg.js?version=1122361
  15. // ==/UserScript==
  16.  
  17. (function () {
  18. "use strict";
  19. var new_element = document.createElement("link");
  20. new_element.setAttribute("rel", "stylesheet");
  21. new_element.setAttribute("href", "https://qmsg.refrain.xyz/message.min.css");
  22. document.body.appendChild(new_element);
  23.  
  24. const button = document.createElement("div");
  25. button.textContent = "导出数据";
  26. Object.assign(button.style, {
  27. height: "34px",
  28. lineHeight: "var(--line-height, 34px)",
  29. width: "90px",
  30. textAlign: "center",
  31. alignItems: "center",
  32. color: "white",
  33. background: "linear-gradient(90deg, rgba(0, 239, 253), rgba(64, 166, 254))",
  34. borderRadius: "5px",
  35. marginLeft: "10px",
  36. fontSize: "13px",
  37. padding: "0 10px",
  38. cursor: "pointer",
  39. fontWeight: "500",
  40. });
  41. button.addEventListener("click", urlClick);
  42.  
  43. //message.js
  44. let loadingMsg = null;
  45.  
  46. //加密数据
  47. let target_data = [];
  48. //密钥
  49. let ptbk = null;
  50.  
  51. (function listen() {
  52. var origin = {
  53. open: XMLHttpRequest.prototype.open,
  54. send: XMLHttpRequest.prototype.send,
  55. };
  56. XMLHttpRequest.prototype.open = function (a, b) {
  57. this.addEventListener("load", replaceFn);
  58. origin.open.apply(this, arguments);
  59. };
  60. XMLHttpRequest.prototype.send = function (a, b) {
  61. origin.send.apply(this, arguments);
  62. };
  63. function replaceFn(obj) {
  64. if (
  65. this?.responseURL?.slice(0, 43) ==
  66. "https://index.baidu.com/api/SearchApi/index"
  67. ) {
  68. let res = JSON.parse(obj?.target?.response);
  69. target_data = res.data.userIndexes;
  70. }
  71. if (
  72. this?.responseURL?.slice(0, 38) ==
  73. "https://index.baidu.com/Interface/ptbk"
  74. ) {
  75. let res = JSON.parse(obj?.target?.response);
  76. ptbk = res.data;
  77. }
  78. }
  79. })();
  80.  
  81. function appendDoc() {
  82. const likeComment = document.querySelector(".index-trend-words");
  83. if (likeComment) {
  84. likeComment.append(button);
  85. return;
  86. }
  87. setTimeout(appendDoc, 1000);
  88. }
  89. appendDoc();
  90.  
  91. let decrypt = function (t, e) {
  92. for (
  93. var n = t.split(""), i = e.split(""), a = {}, r = [], o = 0;
  94. o < n.length / 2;
  95. o++
  96. )
  97. a[n[o]] = n[n.length / 2 + o];
  98. for (var s = 0; s < e.length; s++) r.push(a[i[s]]);
  99. return r.join("");
  100. };
  101.  
  102. /**
  103. * 得到开始和结束日期,得到中间所有天返回数组
  104. * @param {String} startDay 开始日期'2021-7-1'
  105. * @param {String} endDay 结束日期'2021-8-1'
  106. * @return {Array} ['2021-07-01', '2021-07-01'...., '2021-08-01']
  107. */
  108. function getDayArr(startDay, endDay) {
  109. let startVal = moment(startDay).format("YYYY-MM-DD");
  110. let dayArr = [];
  111. while (moment(startVal).isBefore(endDay)) {
  112. dayArr.push(startVal);
  113. // 自增
  114. startVal = moment(startVal).add(1, "day").format("YYYY-MM-DD");
  115. }
  116. // 将结束日期的天放进数组
  117. dayArr.push(moment(endDay).format("YYYY-MM-DD"));
  118. return dayArr;
  119. }
  120.  
  121. function expExcel() {
  122. let dates = getDayArr(target_data[0].all.startDate,target_data[0].all.endDate)
  123. let data = target_data?.map((v,i)=>{
  124. return {
  125. key:v.word[0].name,
  126. value:decrypt(ptbk, v.all.data)?.split(',')?.map((y,z)=>{return {date:dates[z],value:y}}),
  127. }
  128. });
  129. let contrast = {
  130. date: "日期",
  131. value: "值"
  132. };
  133.  
  134. let option = {};
  135. option.fileName = "百度指数"; //文件名
  136. option.datas = data.map(v=>{
  137. return {
  138. sheetName: v.key,
  139. sheetData: v.value,
  140. sheetHeader: Object.values(contrast),
  141. sheetFilter: Object.keys(contrast),
  142. columnWidths: [], // 列宽
  143. }
  144. });
  145. var toExcel = new ExportJsonExcel(option);
  146. toExcel.saveExcel();
  147. loadingMsg.close();
  148. }
  149.  
  150. function urlClick() {
  151. if (target_data.length) {
  152. loadingMsg = Qmsg.loading("正在导出,请勿重复点击!");
  153. expExcel(target_data);
  154. } else {
  155. loadingMsg = Qmsg.error("数据加载失败,请重试");
  156. }
  157. }
  158. })();