// 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, 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, 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, /// 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(()) /// } /// ```