您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Downloading the queries csv export for free subscription users
- // ==UserScript==
- // @name Dune Csv Export
- // @namespace http://tampermonkey.net/
- // @version 0.2.6
- // @description Downloading the queries csv export for free subscription users
- // @author lulu
- // @match https://dune.com/queries*
- // @icon https://www.google.com/s2/favicons?sz=64&domain=dune.com
- // @grant none
- // @require https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js
- // ==/UserScript==
- function getElementByXpath(path){
- return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
- }
- function getNextButton(){
- let path0 = '//*[@id="results"]/div/div[2]/div/div[2]/ul/li[5]/button';
- let path1 = '//*[@id="results"]/div/div[2]/div/div[2]/ul/li[6]/button';
- let btn = getElementByXpath(path0);
- if (btn === null){
- btn = getElementByXpath(path1);
- }
- // console.log("BTN:", btn)
- return btn;
- }
- function getHeaders(table){
- const headers = [];
- $.each($(table).find("thead").find("tr").find("th"), function (key, val2) {
- headers[key] = $(val2).text(); //$(val2).find("div").text();
- });
- return headers;
- }
- async function getCurrentTableValues(){
- const maxAttempts = 100; // Adjust as needed - determines maximum wait time. 50 attempts * 100ms = 5 seconds
- let attempt = 0;
- let table = null;
- const values = [];
- while (attempt < maxAttempts) {
- table = getElementByXpath('//*[@id="results"]/div/div[2]/div/div[1]/table');
- if (table !== null && table !== undefined ) { // check for both null and undefined
- break;
- }
- // console.log("Table is Null, Waiting and Trying again.., attemp: ", attempt);
- // Object is null or undefined, wait and retry
- await new Promise(resolve => setTimeout(resolve, 100));
- attempt++;
- }
- if (table === null || table === undefined ) { // check for both null and undefined
- console.log("Table Did not collected after 100 attempts, Returning Empty!");
- return values;
- }
- $.each($(table).find("tbody tr"), function(rowIndex, rowElement) {
- const row = [];
- $.each($(rowElement).find("td"), function(cellIndex, cellElement) {
- const cellValue = $(cellElement).find("div").first().text();
- row.push(cellValue.trim());
- });
- values.push(row);
- });
- // console.log("VALUES:", values);
- return values;
- }
- async function collect_pages(){
- let table = getElementByXpath('//*[@id="results"]/div/div[2]/div/div[1]/table');
- let custom_limit = document.getElementById("customRowLimit").value;
- const limit = (str => str.trim() === '' ? null : parseInt(str))(custom_limit);
- let hasNextPage = true;
- let collectedData = [];
- do {
- const currValues = await getCurrentTableValues();
- collectedData.push(...currValues);
- const nextButton = getNextButton();
- hasNextPage = Boolean(
- nextButton &&
- !$(nextButton).is(":disabled") &&
- !nextButton.disabled
- );
- if (!$(nextButton).is(":disabled") && nextButton != null){
- $(nextButton).trigger("click");
- await new Promise(resolve => setTimeout(resolve, 20));
- }
- if (limit != null && collectedData.length >= limit) {
- break
- }
- } while (hasNextPage)
- const headers = getHeaders(table);
- download_csv(headers, collectedData);
- }
- function escapeCsvValue(value) {
- if (typeof value !== 'string') value = String(value);
- value = value.replace(/"/g, '""');
- return `"${value}"`;
- }
- function download_csv(headers, rows) {
- let csvHeaders = headers.join(",") + "\n";
- // let csvRows = rows.map(row => row.join(",")).join("\n");
- let csvRows = rows.map(row => row.map(escapeCsvValue).join(",")).join("\n");
- let csvButton = getElementByXpath('//*[@id="results"]/div/div[1]/div[1]/div/button');
- let custom_name = document.getElementById("customNameCsvFileFree").value;
- var downloadBtn = document.createElement("a");
- downloadBtn.href = "data:text/csv;charset=utf-8,"+encodeURI(csvHeaders+csvRows);
- downloadBtn.target = "_blank";
- if (custom_name.length > 1) {
- downloadBtn.download = custom_name+".csv";
- } else {
- let url = window.location.href;
- downloadBtn.download = "query_"+url.split("queries/")[1].replace("/", "_")+".csv"
- }
- downloadBtn.click();
- csvButton.disabled = false;
- }
- async function collectCsv() {
- let csvButton = getElementByXpath('//*[@id="results"]/div/div[1]/div[1]/div/button');
- csvButton.disabled = "disabled";
- let nextButton = getNextButton(); //getElementByXpath('//*[@id="results"]/div/div[2]/div/div[2]/ul/li[5]/button');
- if (nextButton == null){
- // console.log("Butt not exists");
- await collect_pages();
- } else {
- // go to first
- let firstPageBtn = getElementByXpath('//*[@id="results"]/div/div[2]/div/div[2]/ul/li[3]/button');
- if (firstPageBtn != null && !$(firstPageBtn).is(":disabled")){
- $(firstPageBtn).trigger("click");
- await new Promise(resolve => setTimeout(resolve, 5));
- await collect_pages();
- } else {
- await collect_pages();
- }
- }
- }
- function changeCsvButton(){
- // console.log("Running Dune Script");
- let csvButton = getElementByXpath('//*[@id="results"]/div/div[1]/div[1]/div/button');
- if (csvButton != null){
- csvButton.disabled = false;
- csvButton.onclick = collectCsv;
- // adding a input for custom csv file name
- var inp_element = document.createElement('input');
- inp_element.className = "IconButton_iconButton___v3YQ buttonThemes_button__jfRFC buttonThemes_theme-tertiary__v7VoN IconButton_size-M__FIXfN";
- inp_element.id = "customNameCsvFileFree";
- inp_element.placeholder = "Custom filename";
- var limit_inp_element = document.createElement('input');
- limit_inp_element.className = "IconButton_iconButton___v3YQ buttonThemes_button__jfRFC buttonThemes_theme-tertiary__v7VoN IconButton_size-M__FIXfN";
- limit_inp_element.id = "customRowLimit";
- limit_inp_element.placeholder = "Limit Csv Rows";
- limit_inp_element.type = 'number';
- limit_inp_element.min = '0';
- getElementByXpath('//*[@id="results"]/div/div[1]/div[1]').appendChild(inp_element);
- getElementByXpath('//*[@id="results"]/div/div[1]/div[1]').appendChild(limit_inp_element);
- // console.log("BTN CREATED");
- } else {
- setTimeout(()=>{
- changeCsvButton();
- }, 1000)
- }
- }
- (function() {
- 'use strict';
- $(document).ready ( function(){
- changeCsvButton();
- // for (let i = 0; i < 10; i++) {}
- });
- })();