tamper_get_holders_sol_gmgn_nowuse.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. // ==UserScript==
  2. // @name GMGN-Get-Holders
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024-10-19
  5. // @description try to take over the world!
  6. // @author You
  7. // @match https://gmgn.ai/sol/token/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=gmgn.ai
  9. // @grant none
  10. // ==/UserScript==
  11. function funcDownload(content, filename) {
  12. console.log('begin download');
  13. // 创建隐藏的可下载链接
  14. let eleLink = document.createElement('a');
  15. eleLink.download = filename;
  16. eleLink.style.display = 'none';
  17. // 字符内容转变成blob地址
  18. let blob = new Blob([content]);
  19. eleLink.href = URL.createObjectURL(blob);
  20. // 触发点击
  21. document.body.appendChild(eleLink);
  22. eleLink.click();
  23. // 然后移除
  24. document.body.removeChild(eleLink);
  25. }
  26. function sleep(sleepdelay) {
  27. return new Promise((resolve, reject) => {
  28. setTimeout(() => {
  29. resolve(sleepdelay);
  30. }, sleepdelay);
  31. })
  32. }
  33. var number_chars_obj = {
  34. "k": 3,
  35. "m": 6,
  36. "b": 9,
  37. "t": 12,
  38. "p": 15
  39. };
  40. var number_chars_arr = ["k", "m", "b", "t", "p"];
  41. function get_float_number(str_number) {
  42. let float_number = parseFloat(str_number);
  43. for (let number_char of number_chars_arr) {
  44. if (str_number.indexOf(number_char) != -1) {
  45. float_number = parseFloat(str_number) * 10 ** number_chars_obj[number_char];
  46. }
  47. }
  48. return float_number;
  49. }
  50. function getCurrentTime() {
  51. const zeroFill = (i) => {
  52. if (i >= 0 && i <= 9) {
  53. return "0" + i;
  54. } else {
  55. return '' + i;
  56. }
  57. }
  58. let date = new Date();//当前时间
  59. let year = date.getFullYear();
  60. let month = zeroFill(date.getMonth() + 1);//月
  61. let day = zeroFill(date.getDate());//日
  62. let hour = zeroFill(date.getHours());//时
  63. let minute = zeroFill(date.getMinutes());//分
  64. let second = zeroFill(date.getSeconds());//秒
  65. //当前时间
  66. var curTime = month + day + '_' + hour + minute ;
  67. return curTime;
  68. }
  69. function get_thead_arr_holders() {
  70. // let titlearr = _thead.innerText.trim().split(/\r?\n/);
  71. let titlearr = ['Maker', 'Owned_per', 'SOL','inflow_usd', 'Owned_amount',
  72. // 'avg_buy','avg_sell',
  73. 'Buy_counts', 'Sell_counts'];
  74. return titlearr;
  75. }
  76. async function get_tbody_data_holders() {
  77. let div_has_tran_table = document.querySelector("div.chakra-tabs__tab-panels.css-2zi8qu");
  78. let tbody = div_has_tran_table.querySelector("div.ag-body.ag-layout-normal div.ag-center-cols-viewport div.ag-center-cols-container");
  79. let arr_tbody_trs;
  80. arr_tbody_trs = Array.from(tbody.children);
  81. let last_tr = arr_tbody_trs[arr_tbody_trs.length - 1];
  82. let last_row_id = parseInt(last_tr.getAttribute('row-id'));
  83. if (arr_res_data_toptrader.length - 1 >= last_row_id + 1) {
  84. // 这批已经全部获取了
  85. return false;
  86. }
  87. for (let i = 0; i < arr_tbody_trs.length; i++) {
  88. let cur_row_id = parseInt(arr_tbody_trs[i].getAttribute('row-id'));
  89. if (arr_res_data_toptrader.length - 1 >= cur_row_id + 1) {
  90. continue;
  91. }
  92. let arr_tds;
  93. arr_tds = Array.from(arr_tbody_trs[i].children);
  94. let tdtexts = [];
  95. for (let i = 0; i < arr_tds.length; i++) {
  96. if (i == 0) {
  97. // trader
  98. let a_element = arr_tds[i].querySelector("a");
  99. let str_trader = a_element.href.split('/').pop();
  100. tdtexts.push( str_trader);
  101. }
  102. else if (i == 1) {
  103. // Owned%
  104. let str_owned = "0";
  105. let float_sol = 0;
  106. let arr_owned_sol = arr_tds[i].children[0].children;
  107. str_owned = arr_owned_sol[0].innerText.trim().toLowerCase();
  108. str_owned = str_owned.replace(/[%]/g, "").trim();
  109. float_sol = parseFloat(str_owned);
  110. tdtexts.push(float_sol);
  111. } else if (i == 2) {
  112. //sol balance
  113. let str_balance = arr_tds[i].children[0].innerText.trim().replace(/[,]/g, "").trim();
  114. str_balance = str_balance.replace(/\s+/g, "");
  115. console.log("str_balance=",str_balance);
  116. str_balance = str_balance.toLowerCase();
  117. let float_balance = get_float_number(str_balance);
  118. tdtexts.push(float_balance) ;
  119. } else if (i == 3) {
  120. // source/tf time
  121. } else if (i == 4) {
  122. // inflow/Amount
  123. let str_token_amount = "0";
  124. let arr_sol_amount = arr_tds[i].children[0].children;
  125. let str_inflow_amount = arr_sol_amount[0].innerText.trim().toLowerCase();
  126. str_inflow_amount = str_inflow_amount.replace(/[sol$,%\+><]/g, "").trim();
  127. str_token_amount = arr_sol_amount[1].innerText.trim().toLowerCase();
  128. // if (str_token_amount == "--") {
  129. // str_token_amount = "0";
  130. // }
  131. console.log("str_token_amount=",str_token_amount);
  132. let float_token_amount = get_float_number(str_token_amount);
  133. tdtexts.push(str_inflow_amount);
  134. tdtexts.push(float_token_amount/1e6);
  135. } else if (i == 5) {
  136. // pnl
  137. continue;
  138. } else if (i == 6) {
  139. // holding duration
  140. continue;
  141. }else if (i == 7) {
  142. // Avg Cost/Sold
  143. continue;
  144. }
  145. else if (i == 8) {
  146. // Buy/Sell
  147. let str_buysell_counts = arr_tds[i].innerText.trim().toLowerCase();
  148. str_buysell_counts = str_buysell_counts.replace(/[\s+]/g, "").trim();
  149. let arr_buysell_counts = str_buysell_counts.split("/");
  150. let str_buy_counts = arr_buysell_counts[0];
  151. let str_sell_counts = arr_buysell_counts[1];
  152. console.log("str_buy_counts=",str_buy_counts);
  153. console.log("str_sell_counts=",str_sell_counts);
  154. let float_buy_counts = get_float_number(str_buy_counts) ;
  155. let float_sell_counts = get_float_number(str_sell_counts) ;
  156. tdtexts.push( float_buy_counts);
  157. tdtexts.push(float_sell_counts);
  158. continue
  159. } else if (i == 9) {
  160. // Last Active
  161. continue
  162. }
  163. }
  164. arr_res_data_toptrader.push(tdtexts);
  165. }
  166. return true
  167. }
  168. function save_resdata_holders() {
  169. console.log("enter save_resdata_holders");
  170. arr_res_data_toptrader.forEach((val, index, arr) => { arr[index] = val.join() + "\n" });
  171. let urlpathname = window.location.pathname.slice(1).split('/');
  172. urlpathname = urlpathname.pop()
  173. funcDownload(arr_res_data_toptrader.join(""), urlpathname + "_holder_gmgn_sol" + "_" + getCurrentTime() + ".csv");
  174. arr_res_data_toptrader = [];
  175. }
  176. function autoScroll_holders() {
  177. console.log("enter autoScroll_holders");
  178. let interval;
  179. let scroll_times = 15;
  180. let div_has_tran_table = document.querySelector("div.chakra-tabs__tab-panels.css-2zi8qu");
  181. let tbody = div_has_tran_table.querySelector("div.ag-body.ag-layout-normal div.ag-center-cols-viewport div.ag-center-cols-container");
  182. async function down() {
  183. interval = setInterval(async () => {
  184. let tbodytrs;
  185. console.log("scroll_times=", scroll_times);
  186. if (scroll_times > 0) {
  187. await sleep(150);
  188. tbodytrs = tbody.children;
  189. tbodytrs[tbodytrs.length - 1].scrollIntoView({ behavior: "smooth", block: "center" });
  190. let bool_get_tbody = await get_tbody_data_holders();
  191. if (bool_get_tbody == false) {
  192. scroll_times = 0;
  193. }
  194. } else {
  195. clearInterval(interval);
  196. await get_tbody_data_holders();
  197. save_resdata_holders();
  198. return;
  199. }
  200. scroll_times--;
  201. // tbodytrs = tbody.children;
  202. if (arr_res_data_toptrader.length == 101) {
  203. clearInterval(interval);
  204. await get_tbody_data_holders();
  205. save_resdata_holders();
  206. return;
  207. }
  208. await sleep(300);
  209. }, 1200)
  210. }
  211. down()
  212. }
  213. var arr_res_data_toptrader = [];
  214. var res_data_toptrader = [];
  215. // window.addEventListener('load', async () => {
  216. (async function () {
  217. console.log("enter load");
  218. await sleep(6000);
  219. console.log("create button");
  220. var mydivbox = document.createElement("div");
  221. var button_holders = document.createElement("button");//创建 获取 holders 一个按钮
  222. button_holders.className = "tam-mybutton-gettran"
  223. button_holders.textContent = "holder"; //按钮内容
  224. button_holders.style.width = "90px"; //按钮宽度
  225. button_holders.style.height = "20px"; //按钮高度
  226. button_holders.style.align = "center"; //文本居中
  227. button_holders.style.color = "blue"; //按钮文字颜色
  228. button_holders.style.background = "#045710"; //按钮底色
  229. button_holders.style.border = "1px solid #045710"; //边框属性
  230. mydivbox.appendChild(button_holders);
  231. mydivbox.style.position = "fixed";
  232. mydivbox.style.top = "200px";
  233. mydivbox.style.right = "40px";
  234. document.body.appendChild(mydivbox);
  235. button_holders.addEventListener("click", clickButton_get_holders); //监听按钮点击事件
  236. })();
  237. async function clickButton_get_holders() {
  238. arr_res_data_toptrader = [];
  239. console.log("enter clickButton_get_holders arr_res_data_toptrader=", arr_res_data_toptrader);
  240. let div_chakra_tabs = document.querySelector('[role="tablist"]');
  241. let arr_buttons_chakra = Array.from(div_chakra_tabs.querySelectorAll("button"));
  242. let tab_holders_click = undefined;
  243. for (let button of arr_buttons_chakra) {
  244. if (button.innerText.includes("Holders")) {
  245. tab_holders_click = button;
  246. break;
  247. }
  248. }
  249. if (tab_holders_click == undefined) {
  250. console.log("no tab_holders_click");
  251. return;
  252. }
  253. await tab_holders_click.click();
  254. await sleep(7000);
  255. let div_has_tran_table = document.querySelector("div.chakra-tabs__tab-panels.css-2zi8qu");
  256. let _thead = div_has_tran_table.querySelector("div.css-c6kdal div.ag-header-row.ag-header-row-column");
  257. let arr_th = _thead.children;
  258. let tab_click_USD_holder = arr_th[5].querySelector("div.css-1szs8yo");
  259. if (tab_click_USD_holder.innerText.includes("USD")) {
  260. await tab_click_USD_holder.click();
  261. await sleep(4000);
  262. }
  263. let titlearr = get_thead_arr_holders();
  264. arr_res_data_toptrader.push(titlearr);
  265. autoScroll_holders();
  266. }