Skip to content

Instantly share code, notes, and snippets.

@gsusI
Created August 25, 2023 13:27
Show Gist options
  • Save gsusI/684c4ae335b02786ce8aff446c9378d6 to your computer and use it in GitHub Desktop.
Save gsusI/684c4ae335b02786ce8aff446c9378d6 to your computer and use it in GitHub Desktop.
This Tampermonkey user script, named "Twitter Scroll Capture," is designed to capture tweets while scrolling on Twitter. When activated, it adds a "Start Recording" button to the Twitter page, allowing users to record tweets as they scroll through the feed. The captured tweets include details like text, username, handle, time published, URLs, co…
// ==UserScript==
// @name Twitter Scroll Capture
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Capture tweets while scrolling
// @author OpenAI
// @match https://twitter.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
let recording = false;
let tweets = [];
let tweetTexts = new Set();
const recordButton = document.createElement('button');
recordButton.textContent = 'Start Recording';
recordButton.style.position = 'fixed';
recordButton.style.top = '10px';
recordButton.style.right = '10px';
recordButton.style.zIndex = 10000;
recordButton.addEventListener('click', () => {
recording = !recording;
recordButton.textContent = recording ? 'Stop Recording' : 'Start Recording';
if (!recording) {
console.log('Number of tweets captured: ' + tweets.length);
let output = "";
for (let tweet of tweets) {
output += JSON.stringify(tweet) + "\n";
}
console.log(output);
tweets = [];
tweetTexts.clear();
// Copying the output to the clipboard
navigator.clipboard.writeText(output).then(() => {
// Alerting the user that the output has been copied to the clipboard
alert('Output has been copied to the clipboard.');
}).catch(err => {
console.error('Failed to copy text to clipboard:', err);
});
}
});
document.body.appendChild(recordButton);
const observer = new MutationObserver((mutationsList) => {
if (!recording) return;
for(let mutation of mutationsList) {
if (mutation.type === 'childList') {
for (let node of mutation.addedNodes) {
if (node.nodeType === Node.ELEMENT_NODE && node.querySelector('[data-testid="tweet"]')) {
let tweet = {};
let tweetTextElement = node.querySelector('[lang]');
if (tweetTextElement) {
let tweetText = tweetTextElement.innerText;
if (tweetTexts.has(tweetText)) continue;
setTimeout(() => {
tweet.text = tweetText;
tweet.username = node.querySelector('[data-testid="User-Name"] span')?.innerText || '';
tweet.handle = node.querySelector('a[href*="/mattjay"] span')?.innerText || '';
tweet.timePublished = node.querySelector('time')?.getAttribute('datetime') || '';
tweet.urls = Array.from(node.querySelectorAll('a')).map(a => a.href).filter(url => !url.includes('twitter.com')) || [];
tweet.comments = node.querySelector('[data-testid="reply"] span')?.innerText || '0';
tweet.retweets = node.querySelector('[data-testid="retweet"] span')?.innerText || '0';
tweet.likes = node.querySelector('[data-testid="like"] span')?.innerText || '0';
tweet.views = node.querySelector('a[href*="/analytics"] span')?.innerText.replace('K', '000').replace('M', '000000') || '0';
tweets.push(tweet);
tweetTexts.add(tweetText);
console.log('Number of tweets captured: ' + tweets.length);
}, 500);
}
}
}
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment