208 lines
6.7 KiB
Markdown
208 lines
6.7 KiB
Markdown
// INTEGRATION EXAMPLE: Erweiterte main.rs mit VPN-Support
|
|
// ===========================================================
|
|
// Dieses Datei zeigt, wie VPN-Session-Management in die Hauptanwendung
|
|
// integriert wird. Kopieren Sie relevante Teile in Ihre main.rs
|
|
|
|
use anyhow::Result;
|
|
use config::Config;
|
|
use scraper::webdriver::ChromeDriverPool;
|
|
use scraper::vpn_session::VpnSessionManager;
|
|
use scraper::vpn_integration::VpnIntegration;
|
|
use scraper::protonvpn_extension::ProtonVpnAutomater;
|
|
use std::sync::Arc;
|
|
|
|
/// Haupteinstiegspunkt mit VPN-Unterstützung
|
|
#[tokio::main]
|
|
async fn main_with_vpn_example() -> Result<()> {
|
|
// 1. Initialize logging
|
|
tracing_subscriber::fmt()
|
|
.with_max_level(tracing::Level::INFO)
|
|
.with_target(false)
|
|
.init();
|
|
|
|
tracing::info!("🚀 WebScraper starting with VPN support");
|
|
|
|
// 2. Lade Konfiguration
|
|
let config = Config::load().map_err(|err| {
|
|
eprintln!("❌ Failed to load Config: {}", err);
|
|
err
|
|
})?;
|
|
|
|
tracing::info!(
|
|
"✓ Config loaded | VPN: {} | Max Parallel: {}",
|
|
if config.enable_vpn_rotation { "enabled" } else { "disabled" },
|
|
config.max_parallel_tasks
|
|
);
|
|
|
|
// 3. Erstelle VPN-Integration
|
|
let vpn_integration = VpnIntegration::from_config(&config)
|
|
.map_err(|err| {
|
|
eprintln!("❌ Failed to initialize VPN: {}", err);
|
|
err
|
|
})?;
|
|
|
|
// 4. Initialisiere ChromeDriver Pool
|
|
let pool = Arc::new(
|
|
ChromeDriverPool::new(config.max_parallel_tasks).await
|
|
.map_err(|err| {
|
|
eprintln!("❌ Failed to create ChromeDriver pool: {}", err);
|
|
err
|
|
})?
|
|
);
|
|
|
|
tracing::info!("✓ ChromeDriver pool initialized with {} instances",
|
|
pool.get_number_of_instances());
|
|
|
|
// 5. Falls VPN aktiviert: Initialisiere erste Session
|
|
if vpn_integration.enabled {
|
|
if let Err(e) = vpn_integration.initialize_session().await {
|
|
eprintln!("⚠️ Warning: Failed to initialize first VPN session: {}", e);
|
|
eprintln!("Continuing without VPN...");
|
|
}
|
|
}
|
|
|
|
// 6. Führe Updates aus
|
|
tracing::info!("📊 Starting economic data update...");
|
|
if let Err(e) = economic_update_with_vpn(&config, &pool, &vpn_integration).await {
|
|
eprintln!("❌ Economic update failed: {}", e);
|
|
return Err(e);
|
|
}
|
|
|
|
tracing::info!("📊 Starting corporate data update...");
|
|
if let Err(e) = corporate_update_with_vpn(&config, &pool, &vpn_integration).await {
|
|
eprintln!("❌ Corporate update failed: {}", e);
|
|
return Err(e);
|
|
}
|
|
|
|
tracing::info!("✓ All updates completed successfully!");
|
|
Ok(())
|
|
}
|
|
|
|
/// Wrapper für Economic Update mit VPN-Support
|
|
async fn economic_update_with_vpn(
|
|
config: &Config,
|
|
pool: &Arc<ChromeDriverPool>,
|
|
vpn: &VpnIntegration,
|
|
) -> Result<()> {
|
|
// Hier würde die bestehende economic::run_full_update() aufgerufen,
|
|
// aber mit VPN-Integration für jeden Task:
|
|
|
|
// for task in economic_tasks {
|
|
// // Check if VPN rotation is needed
|
|
// if vpn.check_and_rotate_if_needed().await? {
|
|
// tokio::time::sleep(Duration::from_secs(2)).await;
|
|
// }
|
|
//
|
|
// // Execute task
|
|
// execute_task(task, pool).await?;
|
|
//
|
|
// // Increment VPN task counter
|
|
// vpn.increment_task().await;
|
|
// }
|
|
|
|
tracing::info!("Economic update would run here with VPN support");
|
|
Ok(())
|
|
}
|
|
|
|
/// Wrapper für Corporate Update mit VPN-Support
|
|
async fn corporate_update_with_vpn(
|
|
config: &Config,
|
|
pool: &Arc<ChromeDriverPool>,
|
|
vpn: &VpnIntegration,
|
|
) -> Result<()> {
|
|
// Analog zu economic_update_with_vpn
|
|
tracing::info!("Corporate update would run here with VPN support");
|
|
Ok(())
|
|
}
|
|
|
|
// ============================================================================
|
|
// Alternative: Detailliertes Beispiel mit WebDriver-Extension-Loading
|
|
// ============================================================================
|
|
|
|
/// Beispiel: ChromeDriver mit ProtonVPN-Extension laden
|
|
async fn example_create_browser_with_vpn(
|
|
vpn_automater: &ProtonVpnAutomater,
|
|
extension_id: &str,
|
|
) -> Result<()> {
|
|
use std::process::Stdio;
|
|
use tokio::process::Command;
|
|
|
|
// 1. Starten Sie chromedriver mit Extension-Flag
|
|
let mut cmd = Command::new("chromedriver-win64/chromedriver.exe");
|
|
cmd.arg("--port=9222");
|
|
// Hinweis: Chrome-Optionen müssen über Capabilities gesetzt werden,
|
|
// nicht als ChromeDriver-Argumente
|
|
|
|
// 2. Mit fantoccini einen Client erstellen
|
|
let client = fantoccini::ClientBuilder::new()
|
|
.connect("http://localhost:9222")
|
|
.await?;
|
|
|
|
// 3. Optional: Setze Chrome-Optionen für Extension
|
|
// (Dies erfolgt normalerweise automatisch, wenn Extension installiert ist)
|
|
|
|
// 4. Navigiere zu Extension-Popup
|
|
let extension_url = format!("chrome-extension://{}/popup.html", extension_id);
|
|
client.goto(&extension_url).await?;
|
|
|
|
// 5. VPN-Operationen durchführen
|
|
vpn_automater.connect_to_server(&client, "US-Free#1").await?;
|
|
|
|
// 6. Prüfe IP
|
|
let ip = vpn_automater.get_current_ip(&client).await?;
|
|
tracing::info!("Connected with IP: {}", ip);
|
|
|
|
// 7. Navigiere zu Ziel-URL
|
|
client.goto("https://example.com").await?;
|
|
|
|
// 8. Scrape data...
|
|
|
|
client.close().await?;
|
|
Ok(())
|
|
}
|
|
|
|
// ============================================================================
|
|
// Minimales Beispiel für Economic Module
|
|
// ============================================================================
|
|
|
|
/// Wie Sie VPN-Integration in economic::run_full_update() nutzen
|
|
///
|
|
/// Fügen Sie dies zu src/economic/mod.rs hinzu:
|
|
/// ```ignore
|
|
/// pub async fn run_full_update_with_vpn(
|
|
/// config: &Config,
|
|
/// pool: &Arc<ChromeDriverPool>,
|
|
/// vpn: &scraper::vpn_integration::VpnIntegration,
|
|
/// ) -> Result<()> {
|
|
/// let tickers = fetch_economic_tickers().await?;
|
|
///
|
|
/// for (idx, ticker) in tickers.iter().enumerate() {
|
|
/// // Check VPN rotation
|
|
/// if vpn.check_and_rotate_if_needed().await? {
|
|
/// tokio::time::sleep(Duration::from_secs(2)).await;
|
|
/// }
|
|
///
|
|
/// // Execute task
|
|
/// if let Err(e) = pool.execute(
|
|
/// format!("https://example.com/{}", ticker),
|
|
/// |client| async {
|
|
/// // Your scraping logic here
|
|
/// Ok(())
|
|
/// }
|
|
/// ).await {
|
|
/// eprintln!("Failed to process {}: {}", ticker, e);
|
|
/// }
|
|
///
|
|
/// // Increment VPN counter
|
|
/// vpn.increment_task().await;
|
|
///
|
|
/// // Log progress
|
|
/// if (idx + 1) % 10 == 0 {
|
|
/// tracing::info!("Processed {}/{} economic items", idx + 1, tickers.len());
|
|
/// }
|
|
/// }
|
|
///
|
|
/// Ok(())
|
|
/// }
|
|
/// ```
|