Skip to content

Instantly share code, notes, and snippets.

@yutopp
Last active March 1, 2024 08:48
Show Gist options
  • Save yutopp/29b1059bf2bcf6695cd47bd6fb3c012f to your computer and use it in GitHub Desktop.
Save yutopp/29b1059bf2bcf6695cd47bd6fb3c012f to your computer and use it in GitHub Desktop.
2024/3/1時点のTwitter webのDOMの構造でAdツイートのアカウントを自動でブロックするスクリプト
async function blockAdTweetAccount(node) {
// screen-name, idを取得する
var screenName = node.querySelector("div.css-175oi2r.r-1awozwy.r-18u37iz.r-1wbh5a2.r-dnmrzs > div > a > div > div.css-1rynq56.r-bcqeeo.r-qvutc0.r-37j5jr.r-a023e6.r-rjixqe.r-b88u0q.r-1awozwy.r-6koalj.r-1udh08x.r-3s2u2q > span > span")?.innerHTML;
var screenID = node.querySelector("div.css-175oi2r.r-18u37iz.r-1wbh5a2.r-13hce6t > div > div > a > div > span")?.innerHTML;
// console.log(`account: ${screenName} / ${screenID}`);
// 広告のDOMを取得する
var ad = node.querySelector("div > div > div > article > div > div > div.css-175oi2r.r-18u37iz > div.css-175oi2r.r-1iusvr4.r-16y2uox.r-1777fci.r-kzbkwu > div.css-175oi2r.r-zl2h9q > div > div.css-175oi2r.r-1jkjb > div > div.css-1rynq56.r-bcqeeo.r-qvutc0.r-37j5jr.r-a023e6.r-rjixqe.r-16dba41 > span");
if (ad == null) {
return;
}
if (ad.innerHTML != 'Ad') {
return;
}
// Adのツイートをしたアカウントをブロックする
// ハンバーガーメニューをクリックする
var menu = node.querySelector("div > div > div > article > div > div > div.css-175oi2r.r-18u37iz > div.css-175oi2r.r-1iusvr4.r-16y2uox.r-1777fci.r-kzbkwu > div.css-175oi2r.r-zl2h9q > div > div.css-175oi2r.r-1jkjb > div > div.css-175oi2r.r-1awozwy.r-6koalj.r-18u37iz > div > div > div > div > div > div");
menu.click();
// role="menuitem", data-testid="block"のdomをdocumentから取得できるまで待つ
var block = await new Promise(resolve => {
var h = setInterval(() => {
var block = document.querySelector('[role="menuitem"][data-testid="block"]');
if (block != null) {
clearInterval(h);
resolve(block);
}
}, 100);
});
block.click();
// data-testid="confirmationSheetConfirm"のdomをdocumentから取得できるまで待つ
var confirm = await new Promise(resolve => {
var h = setInterval(() => {
var confirm = document.querySelector('[data-testid="confirmationSheetConfirm"]');
if (confirm != null) {
clearInterval(h);
resolve(confirm);
}
}, 100);
});
confirm.click();
// プランアップグレードのモーダルを閉じる
var sheetDialog = await new Promise(resolve => {
var h = setInterval(() => {
var confirm = document.querySelector('[data-testid="sheetDialog"]');
if (confirm != null) {
clearInterval(h);
resolve(confirm);
}
}, 100);
});
var maybeLater = sheetDialog.querySelector("div.css-175oi2r.r-1awozwy.r-16y2uox > div > div > div.css-175oi2r.r-13qz1uu > div");
maybeLater.click();
console.warn(`blocked: ${screenName} / ${screenID}`);
}
async function blockAdTweetAccounts() {
// Twitterのtimelineのツイートのdomを取得する
// data-testid="tweet"のdomをdocumentから全て取得する
var nodes = document.querySelectorAll('[data-testid="tweet"]');
// var nodes = document.querySelectorAll("#react-root > div > div > div.css-175oi2r.r-13qz1uu.r-417010.r-18u37iz > main > div > div > div > div.css-175oi2r.r-kemksi.r-1kqtdi0.r-13l2t4g.r-1ljd8xs.r-1phboty.r-16y2uox.r-184en5c.r-61z16t.r-11wrixw.r-1jgb5lz.r-13qz1uu.r-1ye8kvj > div > div.css-175oi2r.r-1jgb5lz.r-13qz1uu.r-1ye8kvj > div > section > div > div > div");
for (let i = 0; i < nodes.length; i++) {
var node = nodes[i];
try {
await blockAdTweetAccount(node);
}
catch (e) {
console.error(e);
}
}
}
// 定期的に実行する
(async function main() {
while (true) {
await blockAdTweetAccounts();
await new Promise(resolve => setTimeout(resolve, 5000));
}
})().catch(e => console.error(e));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment