|
|
<!DOCTYPE html> |
|
|
<html lang="en" class="bg-gray-900 text-white"> |
|
|
<head> |
|
|
<meta charset="UTF-8" /> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|
|
<title>Social Media Scraper - Terra</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<script src="https://unpkg.com/feather-icons"></script> |
|
|
</head> |
|
|
<body class="flex h-screen overflow-hidden"> |
|
|
|
|
|
|
|
|
<div class="w-64 bg-gray-800 p-4 flex flex-col space-y-4"> |
|
|
<h2 class="text-2xl font-bold mb-4 text-blue-400">Terra OSINT</h2> |
|
|
<button onclick="showSection('dashboard')" class="flex items-center space-x-2 text-gray-300 hover:text-white"> |
|
|
<i data-feather="home"></i><span>Dashboard</span> |
|
|
</button> |
|
|
<button onclick="showSection('config')" class="flex items-center space-x-2 text-gray-300 hover:text-white"> |
|
|
<i data-feather="settings"></i><span>Settings</span> |
|
|
</button> |
|
|
<button onclick="showSection('results')" class="flex items-center space-x-2 text-gray-300 hover:text-white"> |
|
|
<i data-feather="database"></i><span>Results</span> |
|
|
</button> |
|
|
<button onclick="showSection('logs')" class="flex items-center space-x-2 text-gray-300 hover:text-white"> |
|
|
<i data-feather="file-text"></i><span>Logs</span> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="dashboard" class="flex-1 p-6 overflow-auto"> |
|
|
<div class="max-w-3xl mx-auto"> |
|
|
<h1 class="text-3xl font-bold mb-6">Instagram & Twitter Scraper</h1> |
|
|
|
|
|
|
|
|
<div class="bg-gray-800 p-6 rounded-lg mb-6"> |
|
|
<label class="block text-lg font-semibold mb-2">Enter Target Username</label> |
|
|
<input id="targetUsername" type="text" placeholder="e.g. realDonaldTrump" class="w-full p-2 rounded bg-gray-700 text-white" /> |
|
|
<div class="mt-4 flex space-x-4"> |
|
|
<button onclick="startScraping()" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded">Scrape Instagram</button> |
|
|
<button onclick="startScraping()" class="bg-indigo-600 hover:bg-indigo-700 px-4 py-2 rounded">Scrape Twitter</button> |
|
|
<button onclick="startScraping()" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded">Scrape Both</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="status" class="bg-gray-800 p-4 rounded-lg text-center text-gray-400">Ready to scrape</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="config" class="hidden flex-1 p-6 overflow-auto"> |
|
|
<div class="max-w-3xl mx-auto"> |
|
|
<h1 class="text-3xl font-bold mb-6">Configuration</h1> |
|
|
<div class="bg-gray-800 p-6 rounded-lg"> |
|
|
<label class="block text-lg font-semibold mb-2">Instagram Credentials</label> |
|
|
<input id="igUser" type="text" placeholder="Instagram Username" class="w-full mb-2 p-2 rounded bg-gray-700 text-white" /> |
|
|
<input id="igPass" type="password" placeholder="Instagram Password" class="w-full mb-4 p-2 rounded bg-gray-700 text-white" /> |
|
|
|
|
|
<label class="block text-lg font-semibold mb-2">Twitter API Keys</label> |
|
|
<input id="twApiKey" type="text" placeholder="API Key" class="w-full mb-2 p-2 rounded bg-gray-700 text-white" /> |
|
|
<input id="twApiKeySecret" type="text" placeholder="API Key Secret" class="w-full mb-2 p-2 rounded bg-gray-700 text-white" /> |
|
|
<input id="twAccessToken" type="text" placeholder="Access Token" class="w-full mb-2 p-2 rounded bg-gray-700 text-white" /> |
|
|
<input id="twAccessTokenSecret" type="text" placeholder="Access Token Secret" class="w-full mb-4 p-2 rounded bg-gray-700 text-white" /> |
|
|
|
|
|
<div class="flex space-x-4"> |
|
|
<button onclick="saveConfig()" class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded">Save</button> |
|
|
<button onclick="loadConfig()" class="bg-gray-600 hover:bg-gray-700 px-4 py-2 rounded">Load</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="results" class="hidden flex-1 p-6 overflow-auto"> |
|
|
<div class="max-w-5xl mx-auto"> |
|
|
<h1 class="text-3xl font-bold mb-6">Scraping Results</h1> |
|
|
<div class="bg-gray-800 p-6 rounded-lg"> |
|
|
<div class="flex space-x-4 mb-4"> |
|
|
<button onclick="showResultsTab('instagram')" class="bg-pink-600 hover:bg-pink-700 px-4 py-2 rounded">Instagram</button> |
|
|
<button onclick="showResultsTab('twitter')" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded">Twitter</button> |
|
|
</div> |
|
|
|
|
|
<div id="instagramResults" class="hidden"> |
|
|
<h2 class="text-xl font-semibold mb-4">Instagram Mentions & Tags</h2> |
|
|
<div id="instagramOutput" class="bg-gray-900 p-4 rounded max-h-96 overflow-y-auto text-sm text-gray-300"></div> |
|
|
</div> |
|
|
|
|
|
<div id="twitterResults" class="hidden"> |
|
|
<h2 class="text-xl font-semibold mb-4">Twitter Mentions & Hashtags</h2> |
|
|
<div id="twitterOutput" class="bg-gray-900 p-4 rounded max-h-96 overflow-y-auto text-sm text-gray-300"></div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="logs" class="hidden flex-1 p-6 overflow-auto"> |
|
|
<div class="max-w-5xl mx-auto"> |
|
|
<h1 class="text-3xl font-bold mb-6">Scraping Logs</h1> |
|
|
<div class="bg-gray-800 p-6 rounded"> |
|
|
<div id="logOutput" class="bg-black text-green-400 p-4 rounded h-96 overflow-y-auto font-mono text-sm"></div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
function showSection(sectionId) { |
|
|
document.querySelectorAll("#dashboard, #config, #results, #logs").forEach(el => el.classList.add("hidden")); |
|
|
document.getElementById(sectionId).classList.remove("hidden"); |
|
|
} |
|
|
|
|
|
function showResultsTab(tab) { |
|
|
document.getElementById("instagramResults").classList.add("hidden"); |
|
|
document.getElementById("twitterResults").classList.add("hidden"); |
|
|
document.getElementById(tab + "Results").classList.remove("hidden"); |
|
|
} |
|
|
|
|
|
function startScraping() { |
|
|
const username = document.getElementById("targetUsername").value.trim(); |
|
|
if (!username) { |
|
|
alert("Please enter a username."); |
|
|
return; |
|
|
} |
|
|
|
|
|
const status = document.getElementById("status"); |
|
|
status.innerText = `Scraping started for ${username}...`; |
|
|
|
|
|
log(`[${new Date().toLocaleTimeString()}] Starting scrape for ${username}`); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
const result = { |
|
|
instagram: { |
|
|
mentions: [], |
|
|
tags: [{ username: "user123", caption: "Check out this post!", url: "#" }], |
|
|
comments: [] |
|
|
}, |
|
|
twitter: { |
|
|
mentions: [], |
|
|
tags: [{ username: "john_doe", text: "Just mentioned @${username}!", url: "#" }], |
|
|
tweets: [] |
|
|
}, |
|
|
timestamp: new Date().toISOString() |
|
|
}; |
|
|
|
|
|
log(`[${new Date().toLocaleTimeString()}] Scraping completed.`); |
|
|
status.innerText = `Scraping completed for ${username}.`; |
|
|
|
|
|
|
|
|
showResultsTab("instagram"); |
|
|
document.getElementById("instagramOutput").innerText = JSON.stringify(result.instagram, null, 2); |
|
|
document.getElementById("twitterOutput").innerText = JSON.stringify(result.twitter, null, 2); |
|
|
showSection("results"); |
|
|
|
|
|
|
|
|
localStorage.setItem("lastResults", JSON.stringify(result)); |
|
|
localStorage.setItem("lastUsername", username); |
|
|
}, 2000); |
|
|
} |
|
|
|
|
|
function log(message) { |
|
|
const logOutput = document.getElementById("logOutput"); |
|
|
logOutput.innerHTML += message + "\n"; |
|
|
logOutput.scrollTop = logOutput.scrollHeight; |
|
|
} |
|
|
|
|
|
function saveConfig() { |
|
|
const config = { |
|
|
instagram: { |
|
|
username: document.getElementById("igUser").value, |
|
|
password: document.getElementById("igPass").value |
|
|
}, |
|
|
twitter: { |
|
|
api_key: document.getElementById("twApiKey").value, |
|
|
api_key_secret: document.getElementById("twApiKeySecret").value, |
|
|
access_token: document.getElementById("twAccessToken").value, |
|
|
access_token_secret: document.getElementById("twAccessTokenSecret").value |
|
|
} |
|
|
}; |
|
|
localStorage.setItem("scraperConfig", JSON.stringify(config)); |
|
|
alert("Configuration saved."); |
|
|
} |
|
|
|
|
|
function loadConfig() { |
|
|
const config = JSON.parse(localStorage.getItem("scraperConfig")); |
|
|
if (config) { |
|
|
document.getElementById("igUser").value = config.instagram.username || ""; |
|
|
document.getElementById("igPass").value = config.instagram.password || ""; |
|
|
document.getElementById("twApiKey").value = config.twitter.api_key || ""; |
|
|
document.getElementById("twApiKeySecret").value = config.twitter.api_key_secret || ""; |
|
|
document.getElementById("twAccessToken").value = config.twitter.access_token || ""; |
|
|
document.getElementById("twAccessTokenSecret").value = config.twitter.access_token_secret || ""; |
|
|
alert("Configuration loaded."); |
|
|
} else { |
|
|
alert("No saved configuration found."); |
|
|
} |
|
|
} |
|
|
|
|
|
feather.replace(); |
|
|
</script> |
|
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-qwensite.hf.space/logo.svg" alt="qwensite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-qwensite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >QwenSite</a> - 🧬 <a href="https://enzostvs-qwensite.hf.space?remix=6ee5ali/twitter" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
|
</html> |