|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>NeonScraper | Dark Web Explorer</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
|
<script> |
|
|
tailwind.config = { |
|
|
theme: { |
|
|
extend: { |
|
|
colors: { |
|
|
neon: { |
|
|
blue: '#00f2ff', |
|
|
purple: '#9d00ff', |
|
|
pink: '#ff00f2', |
|
|
green: '#00ff9d' |
|
|
}, |
|
|
dark: { |
|
|
900: '#0a0a0a', |
|
|
800: '#1a1a1a', |
|
|
700: '#2a2a2a', |
|
|
600: '#3a3a3a' |
|
|
} |
|
|
}, |
|
|
fontFamily: { |
|
|
'sans': ['Inter', 'ui-sans-serif', 'system-ui'], |
|
|
'mono': ['Fira Code', 'ui-monospace', 'SFMono-Regular'] |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
</script> |
|
|
<style> |
|
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Fira+Code:wght@400;500&display=swap'); |
|
|
|
|
|
body { |
|
|
background-color: #0a0a0a; |
|
|
color: #e5e5e5; |
|
|
font-family: 'Inter', sans-serif; |
|
|
} |
|
|
|
|
|
.neon-glow { |
|
|
box-shadow: 0 0 10px rgba(157, 0, 255, 0.7), |
|
|
0 0 20px rgba(157, 0, 255, 0.5), |
|
|
0 0 30px rgba(157, 0, 255, 0.3); |
|
|
} |
|
|
|
|
|
.neon-text { |
|
|
text-shadow: 0 0 5px rgba(157, 0, 255, 0.7), |
|
|
0 0 10px rgba(157, 0, 255, 0.5); |
|
|
} |
|
|
|
|
|
.input-glow:focus { |
|
|
box-shadow: 0 0 5px rgba(0, 242, 255, 0.7), |
|
|
0 0 10px rgba(0, 242, 255, 0.5); |
|
|
border-color: rgba(0, 242, 255, 0.5); |
|
|
} |
|
|
|
|
|
.tor-status { |
|
|
animation: pulse 2s infinite; |
|
|
} |
|
|
|
|
|
@keyframes pulse { |
|
|
0% { opacity: 1; } |
|
|
50% { opacity: 0.7; } |
|
|
100% { opacity: 1; } |
|
|
} |
|
|
|
|
|
.result-card { |
|
|
transition: all 0.3s ease; |
|
|
border-left: 3px solid transparent; |
|
|
} |
|
|
|
|
|
.result-card:hover { |
|
|
transform: translateY(-2px); |
|
|
border-left: 3px solid #9d00ff; |
|
|
} |
|
|
|
|
|
.loader { |
|
|
border: 3px solid rgba(157, 0, 255, 0.3); |
|
|
border-top: 3px solid #9d00ff; |
|
|
border-radius: 50%; |
|
|
animation: spin 1s linear infinite; |
|
|
} |
|
|
|
|
|
@keyframes spin { |
|
|
0% { transform: rotate(0deg); } |
|
|
100% { transform: rotate(360deg); } |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="min-h-screen bg-dark-900"> |
|
|
<div class="container mx-auto px-4 py-8 max-w-6xl"> |
|
|
|
|
|
<header class="flex items-center justify-between mb-12"> |
|
|
<div class="flex items-center space-x-3"> |
|
|
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-neon-blue to-neon-purple flex items-center justify-center neon-glow"> |
|
|
<i class="fas fa-robot text-white text-xl"></i> |
|
|
</div> |
|
|
<h1 class="text-2xl font-bold text-white neon-text">Neon<span class="text-neon-purple">Scraper</span></h1> |
|
|
</div> |
|
|
<div class="flex items-center space-x-4"> |
|
|
<button id="torCheckBtn" class="px-4 py-2 bg-dark-700 hover:bg-dark-600 rounded-lg flex items-center space-x-2 transition-colors"> |
|
|
<span class="text-sm font-medium">Check Tor Connection</span> |
|
|
<i class="fas fa-shield-alt"></i> |
|
|
</button> |
|
|
<div id="torStatus" class="hidden px-3 py-1 rounded-full text-xs font-medium flex items-center space-x-1"> |
|
|
<span class="w-2 h-2 rounded-full"></span> |
|
|
<span>Status</span> |
|
|
</div> |
|
|
</div> |
|
|
</header> |
|
|
|
|
|
|
|
|
<main> |
|
|
<div class="bg-dark-800 rounded-xl p-6 shadow-lg mb-8 neon-glow"> |
|
|
<div class="flex flex-col md:flex-row md:items-end justify-between mb-6"> |
|
|
<div class="mb-4 md:mb-0"> |
|
|
<h2 class="text-xl font-bold mb-2">Dark Web Explorer</h2> |
|
|
<p class="text-gray-400 text-sm">Enter a .onion URL or search term to begin scraping</p> |
|
|
</div> |
|
|
<div class="flex space-x-3"> |
|
|
<button id="settingsBtn" class="px-3 py-2 bg-dark-700 hover:bg-dark-600 rounded-lg"> |
|
|
<i class="fas fa-cog"></i> |
|
|
</button> |
|
|
<button id="helpBtn" class="px-3 py-2 bg-dark-700 hover:bg-dark-600 rounded-lg"> |
|
|
<i class="fas fa-question-circle"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="relative"> |
|
|
<div class="flex"> |
|
|
<input id="searchInput" type="text" placeholder="Enter .onion URL or search term..." |
|
|
class="input-glow flex-1 px-4 py-3 bg-dark-700 border border-dark-600 rounded-l-lg focus:outline-none focus:border-neon-blue transition-colors"> |
|
|
<button id="searchBtn" class="px-6 py-3 bg-gradient-to-r from-neon-purple to-neon-blue text-white font-medium rounded-r-lg hover:opacity-90 transition-opacity"> |
|
|
<i class="fas fa-search mr-2"></i> Search |
|
|
</button> |
|
|
</div> |
|
|
<div class="mt-2 flex items-center space-x-4 text-xs text-gray-400"> |
|
|
<div class="flex items-center space-x-1"> |
|
|
<i class="fas fa-lock"></i> |
|
|
<span>End-to-end encrypted</span> |
|
|
</div> |
|
|
<div class="flex items-center space-x-1"> |
|
|
<i class="fas fa-user-secret"></i> |
|
|
<span>No logs kept</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="torWarning" class="bg-dark-800 border-l-4 border-neon-purple rounded-lg p-4 mb-8 hidden"> |
|
|
<div class="flex items-start"> |
|
|
<div class="flex-shrink-0 pt-1"> |
|
|
<i class="fas fa-exclamation-triangle text-neon-purple text-xl"></i> |
|
|
</div> |
|
|
<div class="ml-3"> |
|
|
<h3 class="text-lg font-medium text-white">Tor Connection Required</h3> |
|
|
<div class="mt-2 text-sm text-gray-300"> |
|
|
<p>You must be connected to the Tor network to use this service. Please check your Tor connection and try again.</p> |
|
|
</div> |
|
|
<div class="mt-4"> |
|
|
<a href="https://www.torproject.org/download/" target="_blank" class="inline-flex items-center px-3 py-2 bg-neon-purple/20 border border-neon-purple rounded-md text-sm font-medium text-neon-purple hover:bg-neon-purple/30"> |
|
|
<i class="fas fa-download mr-2"></i> Download Tor Browser |
|
|
</a> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="resultsSection" class="hidden"> |
|
|
<div class="flex items-center justify-between mb-4"> |
|
|
<h3 class="text-lg font-medium">Search Results</h3> |
|
|
<div class="text-sm text-gray-400"> |
|
|
<span id="resultCount">0</span> results found |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div id="resultsContainer" class="space-y-4"> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div id="loadingIndicator" class="hidden py-12 flex flex-col items-center justify-center"> |
|
|
<div class="loader w-10 h-10 mb-4"></div> |
|
|
<p class="text-neon-blue">Scraping the dark web...</p> |
|
|
<p class="text-xs text-gray-400 mt-2">This may take some time depending on the site</p> |
|
|
</div> |
|
|
|
|
|
<div id="noResults" class="hidden py-12 text-center"> |
|
|
<i class="fas fa-search text-4xl text-gray-500 mb-4"></i> |
|
|
<h4 class="text-lg font-medium text-gray-300">No results found</h4> |
|
|
<p class="text-gray-500 mt-2">Try a different search term or URL</p> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="sampleResult" class="hidden"> |
|
|
<div class="result-card bg-dark-800 rounded-lg p-4 hover:bg-dark-700 transition-colors"> |
|
|
<div class="flex items-start justify-between"> |
|
|
<div> |
|
|
<h4 class="font-medium text-white mb-1">Example Result</h4> |
|
|
<p class="text-xs text-neon-blue mb-2">http://example.onion</p> |
|
|
<p class="text-sm text-gray-300 line-clamp-2">This is an example result that would show a preview of the scraped content from the dark web. The actual content would be replaced with real data when scraping occurs.</p> |
|
|
</div> |
|
|
<div class="flex space-x-2"> |
|
|
<button class="p-1 text-gray-400 hover:text-neon-blue"> |
|
|
<i class="fas fa-external-link-alt"></i> |
|
|
</button> |
|
|
<button class="p-1 text-gray-400 hover:text-neon-purple"> |
|
|
<i class="fas fa-bookmark"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
<div class="mt-3 pt-2 border-t border-dark-700 flex items-center justify-between"> |
|
|
<div class="flex space-x-3 text-xs text-gray-400"> |
|
|
<span class="flex items-center space-x-1"> |
|
|
<i class="fas fa-calendar-alt"></i> |
|
|
<span>2023-07-15</span> |
|
|
</span> |
|
|
<span class="flex items-center space-x-1"> |
|
|
<i class="fas fa-tag"></i> |
|
|
<span>Marketplace</span> |
|
|
</span> |
|
|
</div> |
|
|
<div class="text-xs text-neon-green"> |
|
|
<span class="px-2 py-1 bg-neon-green/10 rounded">Verified</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</main> |
|
|
|
|
|
|
|
|
<footer class="mt-16 pt-8 border-t border-dark-700 text-center text-gray-500 text-sm"> |
|
|
<div class="flex flex-col md:flex-row justify-center items-center space-y-2 md:space-y-0 md:space-x-6"> |
|
|
<a href="#" class="hover:text-neon-purple transition-colors">Terms of Service</a> |
|
|
<a href="#" class="hover:text-neon-purple transition-colors">Privacy Policy</a> |
|
|
<a href="#" class="hover:text-neon-purple transition-colors">Disclaimer</a> |
|
|
<a href="#" class="hover:text-neon-purple transition-colors">Contact</a> |
|
|
</div> |
|
|
<p class="mt-4">© 2023 NeonScraper. All rights reserved.</p> |
|
|
<p class="mt-2 text-xs text-gray-600">This is a demonstration only. Use responsibly and legally.</p> |
|
|
</footer> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="settingsModal" class="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center z-50 hidden"> |
|
|
<div class="bg-dark-800 rounded-xl p-6 w-full max-w-md neon-glow"> |
|
|
<div class="flex items-center justify-between mb-6"> |
|
|
<h3 class="text-xl font-bold">Settings</h3> |
|
|
<button id="closeSettingsBtn" class="text-gray-400 hover:text-white"> |
|
|
<i class="fas fa-times"></i> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="space-y-6"> |
|
|
<div> |
|
|
<h4 class="font-medium mb-3">Scraping Options</h4> |
|
|
<div class="space-y-3"> |
|
|
<label class="flex items-center space-x-3"> |
|
|
<input type="checkbox" class="form-checkbox rounded bg-dark-700 border-dark-600 text-neon-purple"> |
|
|
<span>Enable JavaScript rendering</span> |
|
|
</label> |
|
|
<label class="flex items-center space-x-3"> |
|
|
<input type="checkbox" class="form-checkbox rounded bg-dark-700 border-dark-600 text-neon-purple" checked> |
|
|
<span>Follow redirects</span> |
|
|
</label> |
|
|
<label class="flex items-center space-x-3"> |
|
|
<input type="checkbox" class="form-checkbox rounded bg-dark-700 border-dark-600 text-neon-purple"> |
|
|
<span>Download media files</span> |
|
|
</label> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<h4 class="font-medium mb-3">Privacy Options</h4> |
|
|
<div class="space-y-3"> |
|
|
<label class="flex items-center space-x-3"> |
|
|
<input type="checkbox" class="form-checkbox rounded bg-dark-700 border-dark-600 text-neon-purple" checked> |
|
|
<span>Clear search history on exit</span> |
|
|
</label> |
|
|
<label class="flex items-center space-x-3"> |
|
|
<input type="checkbox" class="form-checkbox rounded bg-dark-700 border-dark-600 text-neon-purple"> |
|
|
<span>Use random user agents</span> |
|
|
</label> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<h4 class="font-medium mb-2">Tor Proxy Settings</h4> |
|
|
<div class="space-y-2"> |
|
|
<div> |
|
|
<label class="block text-sm text-gray-400 mb-1">Host</label> |
|
|
<input type="text" value="127.0.0.1" class="w-full px-3 py-2 bg-dark-700 border border-dark-600 rounded focus:outline-none focus:border-neon-blue"> |
|
|
</div> |
|
|
<div> |
|
|
<label class="block text-sm text-gray-400 mb-1">Port</label> |
|
|
<input type="text" value="9050" class="w-full px-3 py-2 bg-dark-700 border border-dark-600 rounded focus:outline-none focus:border-neon-blue"> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="mt-8 flex justify-end space-x-3"> |
|
|
<button id="cancelSettingsBtn" class="px-4 py-2 bg-dark-700 hover:bg-dark-600 rounded-lg"> |
|
|
Cancel |
|
|
</button> |
|
|
<button id="saveSettingsBtn" class="px-4 py-2 bg-neon-purple hover:bg-neon-purple/90 rounded-lg"> |
|
|
Save Settings |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="helpModal" class="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center z-50 hidden"> |
|
|
<div class="bg-dark-800 rounded-xl p-6 w-full max-w-2xl neon-glow"> |
|
|
<div class="flex items-center justify-between mb-6"> |
|
|
<h3 class="text-xl font-bold">Help & Information</h3> |
|
|
<button id="closeHelpBtn" class="text-gray-400 hover:text-white"> |
|
|
<i class="fas fa-times"></i> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="space-y-6"> |
|
|
<div> |
|
|
<h4 class="font-medium mb-3 text-neon-blue">Getting Started</h4> |
|
|
<p class="text-gray-300 mb-3">NeonScraper allows you to safely explore and scrape content from the dark web through the Tor network.</p> |
|
|
<ol class="list-decimal list-inside space-y-2 text-gray-300"> |
|
|
<li>Ensure you're connected to Tor (check status in top right)</li> |
|
|
<li>Enter a .onion URL or search term in the input field</li> |
|
|
<li>Click "Search" to begin scraping</li> |
|
|
<li>View results and interact with them as needed</li> |
|
|
</ol> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<h4 class="font-medium mb-3 text-neon-blue">Safety Guidelines</h4> |
|
|
<ul class="list-disc list-inside space-y-2 text-gray-300"> |
|
|
<li>Never enter personal information</li> |
|
|
<li>Don't download files unless you trust the source</li> |
|
|
<li>Be aware that some sites may contain illegal content</li> |
|
|
<li>Use VPN for additional anonymity if desired</li> |
|
|
<li>This tool is for research purposes only</li> |
|
|
</ul> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<h4 class="font-medium mb-3 text-neon-blue">Frequently Asked Questions</h4> |
|
|
<div class="space-y-4"> |
|
|
<div> |
|
|
<h5 class="font-medium text-gray-300">Why do I need Tor?</h5> |
|
|
<p class="text-gray-400 text-sm mt-1">Tor is required to access .onion sites which are only available on the dark web. It also provides anonymity for your searches.</p> |
|
|
</div> |
|
|
<div> |
|
|
<h5 class="font-medium text-gray-300">Is this legal?</h5> |
|
|
<p class="text-gray-400 text-sm mt-1">Accessing the dark web itself is legal in most countries, but the legality depends on what you do with it. Always comply with local laws.</p> |
|
|
</div> |
|
|
<div> |
|
|
<h5 class="font-medium text-gray-300">How are results verified?</h5> |
|
|
<p class="text-gray-400 text-sm mt-1">Verified results come from known, reputable sources that have been vetted by our community.</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="mt-8 flex justify-end"> |
|
|
<button id="closeHelpBtn2" class="px-4 py-2 bg-neon-purple hover:bg-neon-purple/90 rounded-lg"> |
|
|
Got it! |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
|
|
|
const torCheckBtn = document.getElementById('torCheckBtn'); |
|
|
const torStatus = document.getElementById('torStatus'); |
|
|
const torWarning = document.getElementById('torWarning'); |
|
|
const searchBtn = document.getElementById('searchBtn'); |
|
|
const searchInput = document.getElementById('searchInput'); |
|
|
const resultsSection = document.getElementById('resultsSection'); |
|
|
const resultsContainer = document.getElementById('resultsContainer'); |
|
|
const loadingIndicator = document.getElementById('loadingIndicator'); |
|
|
const noResults = document.getElementById('noResults'); |
|
|
const resultCount = document.getElementById('resultCount'); |
|
|
const settingsBtn = document.getElementById('settingsBtn'); |
|
|
const helpBtn = document.getElementById('helpBtn'); |
|
|
const settingsModal = document.getElementById('settingsModal'); |
|
|
const helpModal = document.getElementById('helpModal'); |
|
|
const closeSettingsBtn = document.getElementById('closeSettingsBtn'); |
|
|
const closeHelpBtn = document.getElementById('closeHelpBtn'); |
|
|
const closeHelpBtn2 = document.getElementById('closeHelpBtn2'); |
|
|
const cancelSettingsBtn = document.getElementById('cancelSettingsBtn'); |
|
|
const saveSettingsBtn = document.getElementById('saveSettingsBtn'); |
|
|
|
|
|
|
|
|
let isTorConnected = false; |
|
|
let searchInProgress = false; |
|
|
let torHost = '127.0.0.1'; |
|
|
let torPort = '9050'; |
|
|
|
|
|
|
|
|
torCheckBtn.addEventListener('click', checkTorConnection); |
|
|
searchBtn.addEventListener('click', startSearch); |
|
|
searchInput.addEventListener('keypress', function(e) { |
|
|
if (e.key === 'Enter') startSearch(); |
|
|
}); |
|
|
settingsBtn.addEventListener('click', () => settingsModal.classList.remove('hidden')); |
|
|
helpBtn.addEventListener('click', () => helpModal.classList.remove('hidden')); |
|
|
closeSettingsBtn.addEventListener('click', () => settingsModal.classList.add('hidden')); |
|
|
closeHelpBtn.addEventListener('click', () => helpModal.classList.add('hidden')); |
|
|
closeHelpBtn2.addEventListener('click', () => helpModal.classList.add('hidden')); |
|
|
cancelSettingsBtn.addEventListener('click', () => settingsModal.classList.add('hidden')); |
|
|
saveSettingsBtn.addEventListener('click', saveSettings); |
|
|
|
|
|
|
|
|
async function checkTorConnection() { |
|
|
torCheckBtn.disabled = true; |
|
|
torCheckBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Checking...'; |
|
|
|
|
|
try { |
|
|
const response = await fetch('/check-tor', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ |
|
|
host: torHost, |
|
|
port: torPort |
|
|
}) |
|
|
}); |
|
|
|
|
|
const data = await response.json(); |
|
|
isTorConnected = data.connected; |
|
|
|
|
|
if (isTorConnected) { |
|
|
torStatus.className = 'px-3 py-1 rounded-full text-xs font-medium flex items-center space-x-1 bg-neon-green/20 text-neon-green'; |
|
|
torStatus.innerHTML = '<span class="w-2 h-2 rounded-full bg-neon-green"></span><span>Tor Connected</span>'; |
|
|
torWarning.classList.add('hidden'); |
|
|
} else { |
|
|
torStatus.className = 'px-3 py-1 rounded-full text-xs font-medium flex items-center space-x-1 bg-red-500/20 text-red-500'; |
|
|
torStatus.innerHTML = '<span class="w-2 h-2 rounded-full bg-red-500"></span><span>Tor Disconnected</span>'; |
|
|
torWarning.classList.remove('hidden'); |
|
|
} |
|
|
} catch (error) { |
|
|
console.error('Tor check failed:', error); |
|
|
isTorConnected = false; |
|
|
torStatus.className = 'px-3 py-1 rounded-full text-xs font-medium flex items-center space-x-1 bg-red-500/20 text-red-500'; |
|
|
torStatus.innerHTML = '<span class="w-2 h-2 rounded-full bg-red-500"></span><span>Connection Error</span>'; |
|
|
torWarning.classList.remove('hidden'); |
|
|
} |
|
|
|
|
|
torStatus.classList.remove('hidden'); |
|
|
torCheckBtn.disabled = false; |
|
|
torCheckBtn.innerHTML = '<span class="text-sm font-medium">Check Tor Connection</span><i class="fas fa-shield-alt ml-2"></i>'; |
|
|
} |
|
|
|
|
|
async function startSearch() { |
|
|
if (searchInProgress) return; |
|
|
|
|
|
if (!isTorConnected) { |
|
|
torWarning.classList.remove('hidden'); |
|
|
return; |
|
|
} |
|
|
|
|
|
const query = searchInput.value.trim(); |
|
|
if (!query) return; |
|
|
|
|
|
|
|
|
searchInProgress = true; |
|
|
resultsSection.classList.remove('hidden'); |
|
|
loadingIndicator.classList.remove('hidden'); |
|
|
noResults.classList.add('hidden'); |
|
|
resultsContainer.innerHTML = ''; |
|
|
resultCount.textContent = '0'; |
|
|
searchBtn.disabled = true; |
|
|
searchBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Scraping'; |
|
|
|
|
|
try { |
|
|
const response = await fetch('/scrape', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify({ |
|
|
url: query, |
|
|
host: torHost, |
|
|
port: torPort |
|
|
}) |
|
|
}); |
|
|
|
|
|
const data = await response.json(); |
|
|
|
|
|
if (data.error) { |
|
|
noResults.classList.remove('hidden'); |
|
|
noResults.innerHTML = ` |
|
|
<i class="fas fa-exclamation-triangle text-4xl text-red-500 mb-4"></i> |
|
|
<h4 class="text-lg font-medium text-red-400">Scraping Error</h4> |
|
|
<p class="text-gray-500 mt-2">${data.error}</p> |
|
|
`; |
|
|
} else if (data.results && data.results.length > 0) { |
|
|
resultCount.textContent = data.results.length; |
|
|
displayResults(data.results); |
|
|
} else { |
|
|
noResults.classList.remove('hidden'); |
|
|
} |
|
|
} catch (error) { |
|
|
console.error('Search failed:', error); |
|
|
noResults.classList.remove('hidden'); |
|
|
noResults.innerHTML = ` |
|
|
<i class="fas fa-exclamation-triangle text-4xl text-red-500 mb-4"></i> |
|
|
<h4 class="text-lg font-medium text-red-400">Connection Error</h4> |
|
|
<p class="text-gray-500 mt-2">Failed to connect to the dark web site. Please check your Tor connection.</p> |
|
|
`; |
|
|
} |
|
|
|
|
|
loadingIndicator.classList.add('hidden'); |
|
|
searchInProgress = false; |
|
|
searchBtn.disabled = false; |
|
|
searchBtn.innerHTML = '<i class="fas fa-search mr-2"></i> Search'; |
|
|
} |
|
|
|
|
|
function displayResults(results) { |
|
|
resultsContainer.innerHTML = ''; |
|
|
|
|
|
results.forEach(result => { |
|
|
const resultElement = document.createElement('div'); |
|
|
resultElement.className = 'result-card bg-dark-800 rounded-lg p-4 hover:bg-dark-700 transition-colors'; |
|
|
resultElement.innerHTML = ` |
|
|
<div class="flex items-start justify-between"> |
|
|
<div class="flex-1"> |
|
|
<h4 class="font-medium text-white mb-1">${escapeHtml(result.title || 'Untitled')}</h4> |
|
|
<p class="text-xs text-neon-blue mb-2">${escapeHtml(result.url)}</p> |
|
|
<p class="text-sm text-gray-300">${escapeHtml(result.description || 'No description available')}</p> |
|
|
</div> |
|
|
<div class="flex space-x-2 ml-4"> |
|
|
<button class="p-1 text-gray-400 hover:text-neon-blue" onclick="openInNewTab('${escapeHtml(result.url)}')"> |
|
|
<i class="fas fa-external-link-alt"></i> |
|
|
</button> |
|
|
<button class="p-1 text-gray-400 hover:text-neon-purple"> |
|
|
<i class="fas fa-bookmark"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
<div class="mt-3 pt-2 border-t border-dark-700 flex items-center justify-between"> |
|
|
<div class="flex space-x-3 text-xs text-gray-400"> |
|
|
<span class="flex items-center space-x-1"> |
|
|
<i class="fas fa-calendar-alt"></i> |
|
|
<span>${new Date().toISOString().split('T')[0]}</span> |
|
|
</span> |
|
|
<span class="flex items-center space-x-1"> |
|
|
<i class="fas fa-tag"></i> |
|
|
<span>${result.type || 'Unknown'}</span> |
|
|
</span> |
|
|
</div> |
|
|
${result.verified ? '<div class="text-xs text-neon-green"><span class="px-2 py-1 bg-neon-green/10 rounded">Verified</span></div>' : ''} |
|
|
</div> |
|
|
`; |
|
|
resultsContainer.appendChild(resultElement); |
|
|
}); |
|
|
} |
|
|
|
|
|
function escapeHtml(unsafe) { |
|
|
if (!unsafe) return ''; |
|
|
return unsafe |
|
|
.toString() |
|
|
.replace(/&/g, "&") |
|
|
.replace(/</g, "<") |
|
|
.replace(/>/g, ">") |
|
|
.replace(/"/g, """) |
|
|
.replace(/'/g, "'"); |
|
|
} |
|
|
|
|
|
function openInNewTab(url) { |
|
|
window.open(url, '_blank'); |
|
|
} |
|
|
|
|
|
function saveSettings() { |
|
|
|
|
|
const hostInput = document.querySelector('#settingsModal input[type="text"]:nth-child(1)'); |
|
|
const portInput = document.querySelector('#settingsModal input[type="text"]:nth-child(2)'); |
|
|
|
|
|
if (hostInput && portInput) { |
|
|
torHost = hostInput.value; |
|
|
torPort = portInput.value; |
|
|
} |
|
|
|
|
|
settingsModal.classList.add('hidden'); |
|
|
|
|
|
checkTorConnection(); |
|
|
} |
|
|
|
|
|
|
|
|
window.addEventListener('DOMContentLoaded', checkTorConnection); |
|
|
</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-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=flitrx/dws2" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
|
</html> |