拍蚊神器

自动反对

  1. // ==UserScript==
  2. // @name 拍蚊神器
  3. // @version 0.0.2
  4. // @description 自动反对
  5. // @author jasony
  6. // @include *://*.zhihu.com/*
  7. // @run-at document-body
  8. // @require https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js
  9. // @license MIT
  10. // @grant unsafeWindow
  11. // @grant GM_setValue
  12. // @grant GM_getValue
  13. // @grant GM_xmlhttpRequest
  14. // @grant GM_info
  15. // @namespace https://gf.qytechs.cn/users/151462
  16. // ==/UserScript==
  17.  
  18. (function() {
  19. 'use strict';
  20.  
  21. var state = {
  22. userInfo: null,
  23. trickers: GM_getValue('trickers') ? JSON.parse(GM_getValue('trickers')) : []
  24. };
  25. $.ajaxSetup({
  26. contentType: 'application/json',
  27. dataType: 'json'
  28. });
  29. function throttle(fn, wait) {
  30. wait = wait || 0;
  31. var timerId, lastTime = 0;
  32.  
  33. function throttled() {
  34. var args = arguments;
  35. var currentTime = new Date();
  36. if (currentTime >= lastTime + wait) {
  37. fn.apply(this, args);
  38. lastTime = currentTime;
  39. } else {
  40. if (timerId) {
  41. clearTimeout(timerId);
  42. timerId = null;
  43. }
  44. timerId = setTimeout(function() {
  45. fn.apply(this, args);
  46. }, wait);
  47. }
  48. }
  49. return throttled;
  50. }
  51. function getUserInfo(cb) {
  52. $.get('https://www.zhihu.com/api/v4/me').done(function(info) {
  53. state.userInfo = info;
  54. cb && cb(info);
  55. }).fail(function() {
  56. state.userInfo = null
  57. cb && cb(false);
  58. });
  59. }
  60. function postVoterAnswer(id, type, cb) {
  61. type = type == null ? 'up' : type;
  62. $.post('https://www.zhihu.com/api/v4/answers/' + id + '/voters', JSON.stringify({ type: type })).done(function(info) {
  63. cb && cb(true);
  64. }).fail(function(err) {
  65. cb && cb(false);
  66. });
  67. }
  68. function postVoterArticle(id, voting, cb) {
  69. $.post('https://www.zhihu.com/api/v4/articles/' + id + '/voters', JSON.stringify({ voting: voting })).done(function(info) {
  70. cb && cb(true);
  71. }).fail(function(err) {
  72. cb && cb(false);
  73. });
  74. }
  75. function getAnswers(url_token, cb) {
  76. var answers = [];
  77. $.ajax('https://www.zhihu.com/people/' + url_token + '/answers', { dataType: 'html' }).done(function(htmlStr) {
  78. var initialData = htmlStr && /<script\s+id="js-initialData".*?>(.*?)<\/script>/.exec(htmlStr) && RegExp.$1 && JSON.parse(RegExp.$1);
  79. var answersObj = initialData && initialData.initialState && initialData.initialState.entities && initialData.initialState.entities.answers ? initialData.initialState.entities.answers : {};
  80. if (!$.isEmptyObject(answersObj)) {
  81. for (var k in answersObj) {
  82. answers.push(answersObj[k.toString()]);
  83. }
  84. }
  85. cb && cb(null, answers);
  86. }).fail(function(err) {
  87. cb && cb(err);
  88. });
  89. }
  90. function getPosts(url_token, cb) {
  91. var posts = [];
  92. $.ajax('https://www.zhihu.com/people/' + url_token + '/posts', { dataType: 'html' }).done(function(htmlStr) {
  93. var initialData = htmlStr && /<script\s+id="js-initialData".*?>(.*?)<\/script>/.exec(htmlStr) && RegExp.$1 && JSON.parse(RegExp.$1);
  94. var articlesObj = initialData && initialData.initialState && initialData.initialState.entities && initialData.initialState.entities.articles ? initialData.initialState.entities.articles : {};
  95. if (!$.isEmptyObject(articlesObj)) {
  96. for (var k in articlesObj) {
  97. posts.push(articlesObj[k.toString()]);
  98. }
  99. }
  100. cb && cb(null, posts);
  101. }).fail(function(err) {
  102. cb && cb(err);
  103. });
  104. }
  105. var tGetPosts = throttle(getPosts, 3000);
  106. var tGetAnswers = throttle(getAnswers, 3000);
  107. var tPostVoterAnswer = throttle(postVoterAnswer, 3000);
  108. var tPostVoterPost = throttle(postVoterArticle, 3000);
  109. function batchVote(cb) {
  110. state.trickers.forEach(function(url_token) {
  111. function doPosts(cb) {
  112. tGetPosts(url_token, function(err, posts) {
  113. if (!err && posts && posts.length) {
  114. posts.forEach(function(post, index) {
  115. if (post.voting !== -1) {
  116. tPostVoterPost(post.id, -1);
  117. } else {
  118. console.log(post.title, '已经反对过了,跳过');
  119. }
  120. if (index === posts.length - 1) {
  121. cb && cb();
  122. }
  123. });
  124. } else {
  125. cb && cb();
  126. }
  127. });
  128. }
  129. function doAnswers(cb) {
  130. tGetAnswers(url_token, function(err, answers) {
  131. if (!err && answers && answers.length) {
  132. answers.forEach(function(answer, index) {
  133. if (answer.relationship && answer.relationship.voting !== -1) {
  134. tPostVoterAnswer(answer.id, 'down');
  135. } else {
  136. console.log(answer.excerpt, '已经反对过了,跳过');
  137. }
  138. if (index === answers.length - 1) {
  139. cb && cb();
  140. }
  141. });
  142. } else {
  143. cb && cb();
  144. }
  145. });
  146. }
  147. doPosts(function() {
  148. doAnswers(function() {
  149. cb && cb();
  150. });
  151. });
  152. });
  153. }
  154. var MarkTrickerButton = {
  155. init: function() {
  156. this.url_token = document.location.pathname.split('/')[2];
  157. if (!this.url_token) return;
  158. this.initEvent();
  159. this.render();
  160. },
  161. initEvent: function() {
  162. var that = this;
  163. var url_token = this.url_token;
  164. $('.MemberButtonGroup').on('click', '.MarkTrickerButton--unmark', function() {
  165. state.trickers.push(url_token);
  166. GM_setValue('trickers', JSON.stringify(state.trickers));
  167. that.render();
  168. batchVote();
  169. });
  170. $('.MemberButtonGroup').on('click', '.MarkTrickerButton--marked', function() {
  171. var foundIndex = state.trickers.findIndex(function(tricker) { return tricker === url_token; });
  172. if (foundIndex > -1) {
  173. state.trickers.splice(foundIndex, 1);
  174. GM_setValue('trickers', JSON.stringify(state.trickers));
  175. that.render();
  176. }
  177. });
  178. },
  179. render: function() {
  180. var url_token = this.url_token;
  181. if (!$('.MemberButtonGroup .MarkTrickerButton').length) {
  182. $('.MemberButtonGroup').append('<button class="Button MarkTrickerButton MarkTrickerButton--unmark">标记骗子</button>');
  183. $('.MemberButtonGroup').append('<button class="Button Button--primary Button--red MarkTrickerButton MarkTrickerButton--marked"><span style="display: inline-flex; align-items: center;">&#8203;<svg class="Zi Zi--Ban" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M18.376 5.624c-3.498-3.499-9.254-3.499-12.752 0-3.499 3.498-3.499 9.254 0 12.752 3.498 3.499 9.254 3.499 12.752 0 3.499-3.498 3.499-9.14 0-12.752zm-1.693 1.693c2.37 2.37 2.596 6.094.678 8.69l-9.367-9.48c2.708-1.919 6.32-1.58 8.69.79zm-9.48 9.48c-2.37-2.37-2.595-6.095-.676-8.69l9.48 9.48c-2.822 1.918-6.433 1.58-8.803-.79z" fill-rule="evenodd"></path></svg></span>已标记骗子</button>');
  184. }
  185. var foundUrlToken = state.trickers.find(function(tricker){ return tricker === url_token; });
  186. $('.MarkTrickerButton').hide();
  187. if (foundUrlToken) {
  188. $('.MarkTrickerButton--marked').show();
  189. } else {
  190. $('.MarkTrickerButton--unmark').show();
  191. }
  192. }
  193. };
  194.  
  195. $(function() {
  196. MarkTrickerButton.init();
  197. batchVote();
  198. });
  199. })();

QingJ © 2025

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