📊 Scraper Tutorials
Export data, download videos, and scrape content from X/Twitter
📑 Table of Contents
🎬 Video Downloader
Download any video from X/Twitter tweets. Gets the highest quality available.
How It Works
This script extracts the video URL from the page and opens it in a new tab where you can right-click and save.
- Navigate to a tweet that contains a video
- Open browser console:
Ctrl+Shift+J(Windows) orCmd+Option+J(Mac) - Paste the script below and press Enter
- Video opens in new tab - right-click → "Save Video As"
// Video Downloader - by nichxbt
// Go to: Any tweet with a video
(async () => {
const sleep = ms => new Promise(r => setTimeout(r, ms));
// Try to find video element
let video = document.querySelector('video');
if (!video) {
// Click on video to load it
const mediaContainer = document.querySelector('[data-testid="videoPlayer"]');
if (mediaContainer) {
mediaContainer.click();
await sleep(1000);
video = document.querySelector('video');
}
}
if (!video) {
console.error('❌ No video found on this page!');
alert('No video found! Make sure you are on a tweet with a video.');
return;
}
// Get video sources
const urls = [];
if (video.src) urls.push(video.src);
video.querySelectorAll('source').forEach(s => {
if (s.src) urls.push(s.src);
});
// Check for blob URLs and try to get actual URLs
if (urls.length === 0 || urls[0].startsWith('blob:')) {
console.log('🔍 Looking for video URL in network...');
// Look for video in the page's script data
const scripts = document.querySelectorAll('script');
scripts.forEach(script => {
const match = script.textContent.match(/https:\/\/video\.twimg\.com[^"'\s]+\.mp4[^"'\s]*/g);
if (match) urls.push(...match);
});
}
if (urls.length > 0) {
console.log('🎬 Video URLs found:', urls);
// Open in new tab for easy download
const cleanUrls = [...new Set(urls)].filter(u => !u.startsWith('blob:'));
if (cleanUrls.length > 0) {
window.open(cleanUrls[0], '_blank');
console.log('✅ Opened video in new tab. Right-click → Save As to download.');
} else {
alert('Found blob URL only. Video may use streaming/DRM.');
}
} else {
alert('Could not extract video URL.');
}
})();
For GIFs, the script will find the MP4 version which is higher quality than the animated GIF.
📚 Bookmark Exporter
Export all your X/Twitter bookmarks to a JSON file for backup or analysis.
What It Exports
- Tweet text
- Tweet URL
- Author handle
- Timestamp
- Go to
x.com/i/bookmarks - Open browser console:
Ctrl+Shift+JorCmd+Option+J - Paste the script and press Enter
- Wait while it scrolls through all bookmarks
- JSON file downloads automatically
// Bookmark Exporter - by nichxbt
// Go to: x.com/i/bookmarks
(async () => {
if (!location.pathname.includes('/bookmarks')) {
alert('Please go to x.com/i/bookmarks first!');
return;
}
const sleep = ms => new Promise(r => setTimeout(r, ms));
const bookmarks = [];
let lastCount = 0;
let retries = 0;
console.log('📚 Exporting bookmarks...');
while (retries < 10) {
document.querySelectorAll('article[data-testid="tweet"]').forEach(article => {
const text = article.querySelector('[data-testid="tweetText"]')?.textContent || '';
const timeEl = article.querySelector('time');
const url = timeEl?.closest('a')?.href || '';
const time = timeEl?.getAttribute('datetime') || '';
const userName = article.querySelector('[data-testid="User-Name"]')?.textContent || '';
const handle = userName.match(/@(\w+)/)?.[1] || '';
if (text && !bookmarks.find(b => b.url === url)) {
bookmarks.push({ text, url, handle, time });
console.log(`📖 Found: ${bookmarks.length}`);
}
});
if (bookmarks.length === lastCount) {
retries++;
} else {
retries = 0;
}
lastCount = bookmarks.length;
window.scrollTo(0, document.body.scrollHeight);
await sleep(1500);
}
// Download as JSON
const blob = new Blob([JSON.stringify(bookmarks, null, 2)], { type: 'application/json' });
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'twitter_bookmarks.json';
a.click();
console.log('✅ Exported', bookmarks.length, 'bookmarks!');
alert('Exported ' + bookmarks.length + ' bookmarks to JSON file!');
})();
If you have many bookmarks (1000+), the script may take several minutes. Keep the tab active.
🧵 Thread Unroller
Save any Twitter thread as clean, readable text. Perfect for long threads you want to read later or share.
How It Works
The script identifies all tweets from the thread author, scrolls to load them all, then combines them into a readable format and copies to your clipboard.
- Go to any tweet in a thread
- Open browser console:
Ctrl+Shift+JorCmd+Option+J - Paste the script and press Enter
- Thread is copied to your clipboard!
// Thread Unroller - by nichxbt
// Go to: Any tweet in a thread
(async () => {
const author = location.pathname.match(/\/(\w+)\/status/)?.[1];
if (!author) {
alert('Please navigate to a tweet first!');
return;
}
const sleep = ms => new Promise(r => setTimeout(r, ms));
const tweets = [];
let retries = 0;
console.log(`🧵 Unrolling thread by @${author}...`);
while (retries < 10) {
document.querySelectorAll('article[data-testid="tweet"]').forEach(article => {
const text = article.querySelector('[data-testid="tweetText"]')?.textContent || '';
const userName = article.querySelector('[data-testid="User-Name"]')?.textContent || '';
const handle = userName.match(/@(\w+)/)?.[1] || '';
const url = article.querySelector('time')?.closest('a')?.href || '';
const time = article.querySelector('time')?.getAttribute('datetime') || '';
if (handle.toLowerCase() === author.toLowerCase() && text) {
const exists = tweets.find(t => t.url === url);
if (!exists) {
tweets.push({ text, url, time });
console.log(`📝 Tweet ${tweets.length}`);
}
}
});
window.scrollBy(0, 500);
await sleep(1000);
retries++;
}
// Sort by time (oldest first)
tweets.sort((a, b) => new Date(a.time) - new Date(b.time));
// Format as markdown
const thread = `# 🧵 Thread by @${author}\n\n` +
tweets.map((t, i) => `## Tweet ${i + 1}\n\n${t.text}\n\n---\n`).join('\n');
// Copy to clipboard
await navigator.clipboard.writeText(thread);
console.log(thread);
console.log('\n✅ Thread copied to clipboard!');
alert('Thread unrolled! ' + tweets.length + ' tweets copied to clipboard.');
})();
The thread is formatted as Markdown, making it perfect for pasting into note-taking apps like Notion, Obsidian, or any Markdown editor.