使用 JS 控制台删除推文

问题描述 投票:0回答:5

我正在尝试在我的 Twitter 页面上的 JS 控制台中删除推文。 如果我通过选择按钮然后单击来手动执行,我可以手动运行 3 个不同的功能。

const delButton=()=>{
    document.querySelectorAll('[data-testid="caret"]')[0].click()
};
const clickDel=()=>{
    document.querySelector("#layers > div.css-1dbjc4n.r-1d2f490.r-105ug2t.r-u8s1d.r-zchlnj.r-ipm5af > div > div > div > div:nth-child(2) > div.css-1dbjc4n.r-yfoy6g.r-z2wwpe.r-xnswec.r-1ekmkwe.r-1udh08x.r-u8s1d > div > div > div > div:nth-child(1) > div.css-1dbjc4n.r-16y2uox.r-1wbh5a2 > div > span");
};
const confirmDel=()=>{
    document.querySelector("#layers > div:nth-child(2) > div > div > div > div > div > div.css-1dbjc4n.r-1awozwy.r-1kihuf0.r-18u37iz.r-1pi2tsx.r-1777fci.r-1pjcn9w.r-fxte16.r-1xcajam.r-ipm5af.r-9dcw1g > div.css-1dbjc4n.r-1awozwy.r-yfoy6g.r-1867qdf.r-1jgb5lz.r-pm9dpa.r-1ye8kvj.r-1rnoaur.r-d9fdf6.r-1sxzll1.r-13qz1uu > div.css-1dbjc4n.r-18u37iz.r-13qz1uu > div.css-18t94o4.css-1dbjc4n.r-1dgebii.r-42olwf.r-sdzlij.r-1phboty.r-rs99b7.r-16y2uox.r-1w2pmg.r-1vuscfd.r-1dhvaqw.r-1ny4l3l.r-1fneopy.r-o7ynqc.r-6416eg.r-lrvibr > div > span > span").click()
} 

delButton();
clickDel();
confirmDel();

我尝试了几种不同的方法,如果我通过在控制台中运行每个函数来手动运行它们,它就可以工作。但是,当我尝试将它们放入一个运行所有 3 个的函数时,第二个没有点击,因为它还没有准备好。我在解雇他们之前尝试使用 setTimeout,但它仍然没有用。我也尝试过使用 async 和 await 但我认为我对这个问题的理解是有限的。

const runEmAll=()=>{
    setTimeout(delButton(), 1000); 
    setTimeout(clickDel(), 1000);
    setTimeout(confirmDel(), 1000);
}
runEmAll();

// or I also tried...
const runDel = async ()=>{
    await delButton();
}
runDel().then(clickDel());

再次失败..我得到的错误是

VM1649:2 Uncaught TypeError: Cannot read property 'click' of null

参考clickDel函数

javascript dom settimeout console.log
5个回答
7
投票

.打开 Chrome 或任何浏览器。

(如果浏览器不是,点击顺序和按钮可能会有所不同 铬)。

.打开推特

.单击个人资料或单击推文和回复

.按 F12(开发者选项)

.单击控制台选项卡

.粘贴此代码(推特语言必须是英语)

var delTweets = function () {
var tweetsRemaining = 
document.querySelectorAll('[role="heading"]+div')[1].textContent;
console.log('Remaining: ', tweetsRemaining);
window.scrollBy(0, 10000);
document.querySelectorAll('[aria-label="More"]').forEach(function 
(v, i, a) {
    v.click();
    document.querySelectorAll('span').forEach(function (v2, i2, a2) {
        if (v2.textContent === 'Delete') {
            v2.click();
            document.querySelectorAll('[data-testid="confirmationSheetConfirm"]').forEach(function (v3, i3, a3) {
                v3.click();
            });
        }
        else {
            document.body.click();
        }
    });
});
setTimeout(delTweets, 4000); //less than 4000 might be rate limited or account suspended. increase timeout if any suspend or rate limit happens
}
delTweets();

2
投票

添加到 Mazen Alhrazi 答案(谢谢!),2022 年 12 月 21 日测试,这是有效的:

    (async () => {
      function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
      }
    
      let found;
    
      while (found = document.querySelectorAll('[data-testid="caret"]').length) {
    
        // get first tweet
        let tweet = document.querySelectorAll('[data-testid="tweet"]')[0];
    
        // if it is a retweet, undo it
        if (tweet.querySelectorAll('[data-testid="unretweet"]').length) {
          tweet.querySelectorAll('[data-testid="unretweet"]')[0].click()
          await sleep(1000)
          document.querySelectorAll('[data-testid="unretweetConfirm"]')[0].click()
          await sleep(1000)      
        }
        // is a tweet
        else {
          if (new Date(document.querySelectorAll('[datetime]')[0].getAttribute('datetime')) < new Date('2018')) {
            console.log('Limit date reach')
            break;
          }
    
          tweet.querySelectorAll('[data-testid="caret"]')[0].click()
          await sleep(1000)
          document.querySelectorAll('[role="menuitem"]')[0].click()
          await sleep(1000)
          document.querySelectorAll('[data-testid="confirmationSheetConfirm"]')[0].click()
        }
      }
    
      if (!found)
        console.log('No more tweets found');
    
    })();

我的主要问题是转发在你自己的推文中间,所以你必须删除两者:取消转发和删除取决于类型。

我添加了一个过滤器,因此您不会删除早于

Date
(示例中为 2018 年)的推文。如果不需要,请编辑或删除
if

它并不完美,有些对话/回复有一些问题,但它对我有用。也许其他人会解决这些问题 :)


1
投票

按照 Phix 的建议,我开始工作了,

()=>{
    setTimeout(delButton, 1000); 
    setTimeout(clickDel, 1000);
    setTimeout(confirmDel, 1000);
}

1
投票

登录 > 在您的个人资料上 > 推文选项卡 > 执行

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
document.querySelectorAll('[data-testid="caret"]')[0].click()
await sleep(1000)
document.querySelectorAll('[role="menuitem"]')[0].click()
await sleep(1000)
document.querySelectorAll('[data-testid="confirmationSheetConfirm"]')[0].click()

0
投票

我正在使用 Uzay 的解决方案,但它停止工作了。这是我的解决方案,它也删除了转推。

要使用它,请转到您的 Twitter 时间轴,然后转到“推文”选项卡删除所有推文,或转到“回复”选项卡删除回复。

将以下代码粘贴到浏览器 JavaScript 控制台中。

确保在粘贴之前在代码中设置您的推特句柄!

// IMPORTANT IMPORTANT IMPORTANT - SET YOUR TWITTER HANDLE IN THE NEXT LINE!
// IMPORTANT IMPORTANT IMPORTANT - SET YOUR TWITTER HANDLE IN THE NEXT LINE!
const yourTwitterHandle = "@yourtwitterhandle";
// one every 10 seconds to avoid Twitter noticing
const waitTimeSeconds = 10
const sleep = async (seconds) => new Promise(resolve => setTimeout(resolve, seconds * 1000));
const main = async () => {
    while (true) {
        await walkTweets();
        await sleep(waitTimeSeconds)
    }
}
const walkTweets = async () => {
    let articles = document.getElementsByTagName('article');
    for (article of articles) {
        const spanElements = article.querySelectorAll('span');
        for (spanElement of spanElements) {
            // delete if it is a retweet
            if (spanElement.textContent === "You Retweeted") {
                article.scrollIntoView();
                try {
                    const retweetElement = article.querySelector('[data-testid="unretweet"]');
                    if (retweetElement) {
                        retweetElement.click();
                        document.querySelector('[data-testid="unretweetConfirm"]').click();
                    }
                } catch (e) {}
                return
            }

            if (spanElement.textContent === yourTwitterHandle) {
                // in this case it might be a tweet or a reply
                article.scrollIntoView();
                try {
                    // try to delete a reply
                    const tweetReplyElement = article.querySelectorAll('[aria-label="More"]')[1];
                    if (tweetReplyElement) {
                        tweetReplyElement.click()
                        Array.from(document.getElementsByTagName('*')).find(el => el.textContent.trim() === 'Delete').click()
                        document.querySelector('[data-testid="confirmationSheetConfirm"]').click();
                        return
                    }
                } catch (e) {}

                try {
                    // try to delete a tweet
                    const tweetElement = article.querySelector('[aria-label="More"]');
                    if (tweetElement) {
                        article.scrollIntoView();
                        tweetElement.click()
                        Array.from(document.getElementsByTagName('*')).find(el => el.textContent.trim() === 'Delete').click()
                        document.querySelector('[data-testid="confirmationSheetConfirm"]').click();
                        return
                    }
                } catch (e) {}
            }
        }
    }
}
main()
© www.soinside.com 2019 - 2024. All rights reserved.