Torna al blog

Come configurare un proxy in AWS Lambda per il parsing e le API: guida completa con esempi

Guida passo passo per configurare un proxy in AWS Lambda per il parsing, richieste API e automazione. Esempi di codice in Python e Node.js, soluzione a problemi comuni.

📅18 febbraio 2026
```html

AWS Lambda è una piattaforma serverless che consente di eseguire codice senza gestire server. Tuttavia, quando si lavora con il parsing di siti web, API di marketplace o automazione di attività, spesso si presenta un problema: le funzioni Lambda utilizzano indirizzi IP di AWS, che sono facilmente rilevabili e bloccabili. In questa guida vedremo come integrare i proxy in Lambda, configurare la rotazione degli IP e evitare errori comuni.

L'articolo è rivolto agli sviluppatori che automatizzano attività tramite AWS Lambda: parsing di dati da siti protetti, monitoraggio dei prezzi dei concorrenti, lavoro con API di social media o marketplace. Otterrete esempi di codice pronti all'uso in Python e Node.js, che possono essere utilizzati immediatamente dopo la lettura.

Perché utilizzare i proxy in AWS Lambda

AWS Lambda utilizza per impostazione predefinita indirizzi IP dal pool di Amazon Web Services. Questi indirizzi si trovano in elenchi pubblici e sono facilmente identificabili dai sistemi di protezione contro i bot. Ecco i principali scenari in cui i proxy diventano necessari:

Caso reale: Uno sviluppatore ha configurato Lambda per monitorare i prezzi su Wildberries ogni 15 minuti. Dopo 2 giorni, il marketplace ha iniziato a restituire l'errore 403 Forbidden: l'IP di AWS è stato inserito nella blacklist. Dopo aver collegato proxy residenziali, il parsing funziona stabilmente da 6 mesi.

Principali motivi per utilizzare i proxy in Lambda:

  • Parsing di siti protetti: Molti siti bloccano le richieste dagli IP dei data center AWS. I proxy consentono di mascherare Lambda come utenti normali.
  • Limitazioni geolocalizzate: Se è necessario ottenere dati da un sito accessibile solo da un determinato paese (ad esempio, prezzi regionali su Ozon), i proxy con la geolocalizzazione desiderata risolvono il problema.
  • Bypass del rate limiting: Le API di molti servizi limitano il numero di richieste da un singolo IP. La rotazione dei proxy consente di distribuire il carico.
  • A/B testing della pubblicità: Verifica della visualizzazione degli annunci pubblicitari da diverse regioni per analizzare i concorrenti.
  • Monitoraggio dei marketplace: Monitoraggio delle posizioni dei prodotti, dei prezzi dei concorrenti su Wildberries, Ozon, Avito senza blocchi.

Le funzioni Lambda vengono spesso eseguite su base programmata (tramite CloudWatch Events) o su trigger, rendendole uno strumento ideale per l'automazione. Tuttavia, senza proxy, tali attività si imbattono rapidamente in blocchi da parte delle risorse target.

Quale tipo di proxy scegliere per Lambda

La scelta del tipo di proxy dipende dall'attività che la tua funzione Lambda deve svolgere. Esaminiamo tre tipi principali e il loro utilizzo nell'architettura serverless:

Tipo di proxy Velocità Anonimato Migliori scenari per Lambda
Proxy dei data center Molto alta (50-200 ms) Media Parsing API senza protezione rigorosa, controlli di disponibilità di massa, monitoraggio SEO
Proxy residenziali Media (300-800 ms) Molto alta Parsing di siti protetti (marketplace, social media), bypass di Cloudflare, lavoro con API di Instagram/Facebook
Proxy mobili Media (400-1000 ms) Massima Lavoro con API mobili (TikTok, Instagram), test di pubblicità mobile, bypass delle protezioni più rigorose

Raccomandazioni per la scelta:

  • Per il parsing di Wildberries, Ozon, Avito: Utilizzare proxy residenziali con geolocalizzazione russa. Queste piattaforme bloccano attivamente gli IP dei data center.
  • Per il monitoraggio di API senza protezione rigorosa: I proxy dei data center sono sufficienti, sono più economici e veloci.
  • Per lavorare con API di Instagram, Facebook, TikTok: Solo proxy mobili o residenziali: queste piattaforme rilevano e bloccano i data center.
  • Per bypassare Cloudflare, PerimeterX: Proxy residenziali con rotazione, preferibilmente con sessioni sticky (mantenimento dell'IP per 5-30 minuti).

Importante: Le funzioni Lambda hanno un limite di tempo di esecuzione (massimo 15 minuti). Quando si utilizzano proxy lenti (residenziali/mobili), tenere conto dei ritardi: se una richiesta tramite proxy richiede 2 secondi, in 15 minuti si possono effettuare al massimo ~450 richieste.

Configurazione dei proxy in Lambda con Python (requests, urllib3)

Python è il linguaggio più popolare per le funzioni Lambda, soprattutto per le attività di parsing e automazione. Vediamo come configurare i proxy con la libreria requests, utilizzata nel 90% dei casi.

Configurazione di base del proxy HTTP

Il modo più semplice per collegare un proxy è passare il parametro proxies nel metodo requests.get():

import requests
import os

def lambda_handler(event, context):
    # Otteniamo le credenziali del proxy dalle variabili di ambiente
    proxy_host = os.environ['PROXY_HOST']  # Ad esempio: proxy.example.com
    proxy_port = os.environ['PROXY_PORT']  # Ad esempio: 8080
    proxy_user = os.environ['PROXY_USER']
    proxy_pass = os.environ['PROXY_PASS']
    
    # Formiamo l'URL del proxy con autorizzazione
    proxy_url = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
    
    proxies = {
        'http': proxy_url,
        'https': proxy_url
    }
    
    try:
        # Effettuiamo una richiesta tramite il proxy
        response = requests.get(
            'https://api.example.com/data',
            proxies=proxies,
            timeout=10  # Importante! Impostare un timeout
        )
        
        return {
            'statusCode': 200,
            'body': response.text
        }
    
    except requests.exceptions.ProxyError as e:
        print(f"Errore proxy: {e}")
        return {
            'statusCode': 500,
            'body': 'Connessione proxy fallita'
        }
    
    except requests.exceptions.Timeout as e:
        print(f"Errore timeout: {e}")
        return {
            'statusCode': 504,
            'body': 'Timeout della richiesta'
        }

Punti chiave di questo codice:

  • Variabili di ambiente: Non memorizzare mai le credenziali del proxy direttamente nel codice! Utilizzare le variabili di ambiente nelle impostazioni di Lambda.
  • Timeout: Assicurati di impostare un timeout (10-30 secondi). Senza di esso, Lambda potrebbe bloccarsi fino al termine del tempo massimo di esecuzione.
  • Gestione degli errori: I proxy possono essere non disponibili o lenti: gestisci sempre le eccezioni ProxyError e Timeout.
  • HTTP e HTTPS: Specifica entrambi i protocolli nel dizionario proxies, anche se utilizzi solo HTTPS.

Configurazione del proxy SOCKS5

I proxy SOCKS5 offrono un livello di anonimato più elevato e funzionano a livello TCP, rendendoli invisibili per alcuni sistemi di protezione. Per lavorare con SOCKS5 in requests è necessaria la libreria requests[socks]:

import requests
import os

def lambda_handler(event, context):
    proxy_host = os.environ['PROXY_HOST']
    proxy_port = os.environ['PROXY_PORT']
    proxy_user = os.environ['PROXY_USER']
    proxy_pass = os.environ['PROXY_PASS']
    
    # Proxy SOCKS5 con autorizzazione
    proxy_url = f"socks5://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
    
    proxies = {
        'http': proxy_url,
        'https': proxy_url
    }
    
    try:
        response = requests.get(
            'https://www.wildberries.ru/catalog/12345/detail.aspx',
            proxies=proxies,
            timeout=15
        )
        
        # Parsing dei dati
        return {
            'statusCode': 200,
            'body': response.text
        }
    
    except Exception as e:
        print(f"Errore: {e}")
        return {
            'statusCode': 500,
            'body': str(e)
        }

Importante per il deployment in Lambda: Quando utilizzi SOCKS5, aggiungi a requirements.txt:

requests[socks]
PySocks

Verifica dell'IP tramite proxy

Prima di eseguire la logica principale, è utile verificare che il proxy funzioni e restituisca l'IP corretto:

def check_proxy_ip(proxies):
    """Controlla l'IP visibile al mondo esterno tramite proxy"""
    try:
        response = requests.get(
            'https://api.ipify.org?format=json',
            proxies=proxies,
            timeout=10
        )
        ip_data = response.json()
        print(f"IP attuale tramite proxy: {ip_data['ip']}")
        return ip_data['ip']
    except Exception as e:
        print(f"Verifica proxy fallita: {e}")
        return None

def lambda_handler(event, context):
    # ... configurazione del proxy ...
    
    # Verifichiamo l'IP prima del lavoro principale
    current_ip = check_proxy_ip(proxies)
    if not current_ip:
        return {
            'statusCode': 500,
            'body': 'Verifica del proxy fallita'
        }
    
    # Logica principale del parsing
    # ...

Configurazione dei proxy in Lambda con Node.js (axios, got)

Node.js è il secondo linguaggio più popolare per le funzioni Lambda, soprattutto quando è necessaria un'elevata prestazione nel lavoro con le API. Vediamo come configurare i proxy con le librerie axios e got.

Configurazione con axios

Axios è la libreria HTTP più popolare per Node.js. Per lavorare con i proxy è necessario un pacchetto aggiuntivo https-proxy-agent:

const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');

exports.handler = async (event) => {
    // Otteniamo le credenziali dalle variabili di ambiente
    const proxyHost = process.env.PROXY_HOST;
    const proxyPort = process.env.PROXY_PORT;
    const proxyUser = process.env.PROXY_USER;
    const proxyPass = process.env.PROXY_PASS;
    
    // Formiamo l'URL del proxy
    const proxyUrl = `http://${proxyUser}:${proxyPass}@${proxyHost}:${proxyPort}`;
    
    // Creiamo un agente per il proxy
    const agent = new HttpsProxyAgent(proxyUrl);
    
    try {
        const response = await axios.get('https://api.example.com/data', {
            httpsAgent: agent,
            timeout: 10000  // 10 secondi
        });
        
        return {
            statusCode: 200,
            body: JSON.stringify(response.data)
        };
    } catch (error) {
        console.error('Richiesta fallita:', error.message);
        
        return {
            statusCode: 500,
            body: JSON.stringify({
                error: error.message
            })
        };
    }
};

Installazione delle dipendenze: Aggiungi a package.json:

{
  "dependencies": {
    "axios": "^1.6.0",
    "https-proxy-agent": "^7.0.0"
  }
}

Configurazione SOCKS5 con axios

Per i proxy SOCKS5 utilizza il pacchetto socks-proxy-agent:

const axios = require('axios');
const { SocksProxyAgent } = require('socks-proxy-agent');

exports.handler = async (event) => {
    const proxyUrl = `socks5://${process.env.PROXY_USER}:${process.env.PROXY_PASS}@${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`;
    
    const agent = new SocksProxyAgent(proxyUrl);
    
    try {
        const response = await axios.get('https://www.ozon.ru/api/products', {
            httpAgent: agent,
            httpsAgent: agent,
            timeout: 15000
        });
        
        return {
            statusCode: 200,
            body: JSON.stringify(response.data)
        };
    } catch (error) {
        console.error('Errore:', error.message);
        return {
            statusCode: 500,
            body: JSON.stringify({ error: error.message })
        };
    }
};

Alternativa: libreria got

Got è una libreria HTTP moderna con supporto nativo per i proxy (non richiede agenti separati):

const got = require('got');

exports.handler = async (event) => {
    const proxyUrl = `http://${process.env.PROXY_USER}:${process.env.PROXY_PASS}@${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`;
    
    try {
        const response = await got('https://api.example.com/data', {
            agent: {
                http: new (require('http-proxy-agent'))(proxyUrl),
                https: new (require('https-proxy-agent'))(proxyUrl)
            },
            timeout: {
                request: 10000
            },
            responseType: 'json'
        });
        
        return {
            statusCode: 200,
            body: JSON.stringify(response.body)
        };
    } catch (error) {
        console.error('Errore:', error.message);
        return {
            statusCode: 500,
            body: JSON.stringify({ error: error.message })
        };
    }
};

Rotazione dei proxy in Lambda: come cambiare IP automaticamente

La rotazione dei proxy è critica per le attività in cui è necessario effettuare molte richieste senza blocchi. Ci sono due approcci principali: utilizzare servizi di proxy con rotazione automatica o gestire manualmente un pool di proxy.

Rotazione automatica tramite fornitore

La maggior parte dei fornitori di proxy residenziali (incluso ProxyCove) fornisce un endpoint con rotazione automatica: ogni richiesta o ogni N minuti l'IP cambia automaticamente:

import requests
import os

def lambda_handler(event, context):
    # Proxy con rotazione automatica
    # Formato: rotating.proxy.com:port
    # Ogni richiesta = nuovo IP
    proxy_url = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@rotating.proxycove.com:8080"
    
    proxies = {
        'http': proxy_url,
        'https': proxy_url
    }
    
    results = []
    
    # Effettuiamo 10 richieste - ognuna con un nuovo IP
    for i in range(10):
        try:
            response = requests.get(
                f'https://api.wildberries.ru/products/{i}',
                proxies=proxies,
                timeout=10
            )
            results.append({
                'product_id': i,
                'status': response.status_code,
                'data': response.json()
            })
        except Exception as e:
            results.append({
                'product_id': i,
                'error': str(e)
            })
    
    return {
        'statusCode': 200,
        'body': json.dumps(results)
    }

Rotazione manuale da un pool di proxy

Se hai un elenco di proxy, puoi implementare la rotazione manualmente. Questo è utile quando hai bisogno di controllare quale proxy viene utilizzato per ogni richiesta:

import requests
import random
import json

def lambda_handler(event, context):
    # Elenco dei proxy (può essere memorizzato in DynamoDB o S3)
    proxy_pool = [
        {
            'host': 'proxy1.example.com',
            'port': '8080',
            'user': 'user1',
            'pass': 'pass1'
        },
        {
            'host': 'proxy2.example.com',
            'port': '8080',
            'user': 'user2',
            'pass': 'pass2'
        },
        {
            'host': 'proxy3.example.com',
            'port': '8080',
            'user': 'user3',
            'pass': 'pass3'
        }
    ]
    
    results = []
    
    for i in range(10):
        # Scegliamo un proxy casuale dal pool
        proxy = random.choice(proxy_pool)
        proxy_url = f"http://{proxy['user']}:{proxy['pass']}@{proxy['host']}:{proxy['port']}"
        
        proxies = {
            'http': proxy_url,
            'https': proxy_url
        }
        
        try:
            response = requests.get(
                f'https://api.example.com/item/{i}',
                proxies=proxies,
                timeout=10
            )
            results.append({
                'item': i,
                'proxy_used': proxy['host'],
                'status': response.status_code
            })
        except Exception as e:
            results.append({
                'item': i,
                'proxy_used': proxy['host'],
                'error': str(e)
            })
    
    return {
        'statusCode': 200,
        'body': json.dumps(results)
    }

Sticky sessions per mantenere l'IP

Alcune attività richiedono di mantenere un IP durante la sessione (ad esempio, autenticazione su un sito). I fornitori di proxy offrono sticky sessions tramite un parametro nell'URL:

import requests
import uuid

def lambda_handler(event, context):
    # Generiamo un session_id unico
    session_id = str(uuid.uuid4())
    
    # Proxy con sticky session (IP mantenuto per 10 minuti)
    proxy_url = f"http://{os.environ['PROXY_USER']}-session-{session_id}:{os.environ['PROXY_PASS']}@sticky.proxycove.com:8080"
    
    proxies = {
        'http': proxy_url,
        'https': proxy_url
    }
    
    # Tutte le richieste in questa Lambda verranno eseguite con lo stesso IP
    # 1. Autenticazione
    login_response = requests.post(
        'https://example.com/login',
        data={'user': 'test', 'pass': 'test'},
        proxies=proxies
    )
    
    # 2. Ottenere dati (viene utilizzato lo stesso IP)
    data_response = requests.get(
        'https://example.com/dashboard',
        proxies=proxies,
        cookies=login_response.cookies
    )
    
    return {
        'statusCode': 200,
        'body': data_response.text
    }

Memorizzazione delle credenziali del proxy tramite variabili di ambiente

Non memorizzare mai le credenziali del proxy (nome utente, password, host) direttamente nel codice della funzione Lambda. AWS offre diversi modi sicuri per memorizzare dati sensibili:

1. Variabili di ambiente (modo base)

Nella console AWS Lambda → Configurazione → Variabili di ambiente aggiungi:

  • PROXY_HOST = proxy.example.com
  • PROXY_PORT = 8080
  • PROXY_USER = your_username
  • PROXY_PASS = your_password

AWS cripta automaticamente le variabili di ambiente a riposo. Accesso nel codice:

# Python
import os
proxy_host = os.environ['PROXY_HOST']

// Node.js
const proxyHost = process.env.PROXY_HOST;

2. AWS Secrets Manager (raccomandato per la produzione)

Per la massima sicurezza, utilizza AWS Secrets Manager: fornisce rotazione automatica dei segreti e controllo dettagliato degli accessi:

import boto3
import json
from botocore.exceptions import ClientError

def get_proxy_credentials():
    secret_name = "proxy-credentials"
    region_name = "us-east-1"
    
    session = boto3.session.Session()
    client = session.client(
        service_name='secretsmanager',
        region_name=region_name
    )
    
    try:
        get_secret_value_response = client.get_secret_value(
            SecretId=secret_name
        )
        secret = json.loads(get_secret_value_response['SecretString'])
        return secret
    except ClientError as e:
        print(f"Errore nel recupero del segreto: {e}")
        raise e

def lambda_handler(event, context):
    # Otteniamo le credenziali da Secrets Manager
    creds = get_proxy_credentials()
    
    proxy_url = f"http://{creds['user']}:{creds['password']}@{creds['host']}:{creds['port']}"
    
    # Utilizziamo il proxy
    # ...

Importante: Non dimenticare di aggiungere i diritti IAM alla funzione Lambda per accedere a Secrets Manager:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue"
      ],
      "Resource": "arn:aws:secretsmanager:us-east-1:123456789:secret:proxy-credentials-*"
    }
  ]
}

Errori comuni e loro risoluzione

Quando si lavora con i proxy in Lambda, gli sviluppatori spesso si imbattono negli stessi problemi. Esaminiamo i più comuni e i modi per risolverli:

Errore: ProxyError / Timeout di connessione

Sintomo: requests.exceptions.ProxyError: HTTPConnectionPool(host='proxy.example.com', port=8080): Max retries exceeded

Cause:

  • Credenziali proxy errate (nome utente/password)
  • Server proxy non disponibile o sovraccarico
  • Firewall blocca le connessioni in uscita di Lambda
  • Timeout troppo breve

Soluzione:

# 1. Controlla le credenziali
print(f"Utilizzo proxy: {proxy_host}:{proxy_port}")
print(f"Utente: {proxy_user}")

# 2. Aumenta il timeout
response = requests.get(url, proxies=proxies, timeout=30)

# 3. Aggiungi logica di retry
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

session = requests.Session()
retry = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)

response = session.get(url, proxies=proxies, timeout=30)

Errore: Verifica del certificato SSL fallita

Sintomo: SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]

Cause: Alcuni proxy (soprattutto quelli economici) utilizzano certificati SSL autofirmati.

Soluzione (utilizzare con cautela!):

# Disabilita la verifica SSL (solo per test!)
response = requests.get(
    url,
    proxies=proxies,
    verify=False  # NON utilizzare in produzione!
)

# Meglio: specifica il percorso del certificato CA
response = requests.get(
    url,
    proxies=proxies,
    verify='/path/to/ca-bundle.crt'
)

Importante: Disabilitare la verifica SSL (verify=False) rende la connessione vulnerabile ad attacchi man-in-the-middle. Utilizzare solo per il debug in ambienti di sviluppo!

Errore: Timeout di Lambda (Task timed out after X seconds)

Sintomo: La funzione Lambda termina con un errore di timeout, senza attendere la risposta dal proxy.

Cause: Proxy lenti (soprattutto residenziali/mobili) + grande numero di richieste.

Soluzione:

  • Aumenta il timeout della funzione Lambda: Configurazione → Configurazione generale → Timeout (massimo 15 minuti)
  • Riduci il numero di richieste per esecuzione
  • Utilizza richieste asincrone (asyncio in Python, Promise.all in Node.js)
  • Cambia a proxy più veloci per attività non critiche
# Python: richieste asincrone per accelerare
import asyncio
import aiohttp

async def fetch_url(session, url, proxy):
    async with session.get(url, proxy=proxy, timeout=10) as response:
        return await response.text()

async def lambda_handler_async(event, context):
    proxy_url = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@{os.environ['PROXY_HOST']}:{os.environ['PROXY_PORT']}"
    
    urls = [f'https://api.example.com/item/{i}' for i in range(50)]
    
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_url(session, url, proxy_url) for url in urls]
        results = await asyncio.gather(*tasks)
    
    return {
        'statusCode': 200,
        'body': json.dumps({'count': len(results)})
    }

def lambda_handler(event, context):
    return asyncio.run(lambda_handler_async(event, context))

Errore: 407 Proxy Authentication Required

Sintomo: Errore HTTP 407 durante il tentativo di utilizzare il proxy.

Cause: Formato errato nella trasmissione delle credenziali o il proxy richiede l'autenticazione IP invece di nome utente/password.

Soluzione:

# Controlla il formato dell'URL del proxy
# Corretto:
proxy_url = f"http://{user}:{password}@{host}:{port}"

# Errato (protocollo mancante):
proxy_url = f"{user}:{password}@{host}:{port}"  # ❌

# Se il proxy richiede l'autenticazione IP:
# 1. Scopri l'IP esterno della tua Lambda (può cambiare!)
# 2. Aggiungi questo IP alla whitelist del fornitore di proxy
# 3. Utilizza il proxy senza user:pass

# Ottenere l'IP esterno di Lambda:
response = requests.get('https://api.ipify.org?format=json')
lambda_ip = response.json()['ip']
print(f"IP esterno di Lambda: {lambda_ip}")

Ottimizzazione delle prestazioni di Lambda con i proxy

L'utilizzo di proxy aggiunge latenza a ogni richiesta. Ecco alcuni modi collaudati per minimizzare l'impatto sulle prestazioni:

1. Connection pooling

Riutilizza le connessioni TCP invece di crearne una nuova per ogni richiesta:

# Python: utilizza Session invece di requests.get()
import requests

# Crea sessione una volta (può essere spostata all'esterno del handler)
session = requests.Session()
session.proxies = {
    'http': proxy_url,
    'https': proxy_url
}

def lambda_handler(event, context):
    # Tutte le richieste riutilizzano le connessioni
    for i in range(100):
        response = session.get(f'https://api.example.com/item/{i}')
        # elabora la risposta...

2. Richieste parallele

Se è necessario effettuare molte richieste indipendenti, esegui le richieste in parallelo:

// Node.js: richieste parallele con Promise.all
const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');

const agent = new HttpsProxyAgent(proxyUrl);

exports.handler = async (event) => {
    const urls = Array.from({length: 50}, (_, i) => 
        `https://api.example.com/item/${i}`
    );
    
    // Tutte le richieste vengono eseguite in parallelo
    const promises = urls.map(url => 
        axios.get(url, { 
            httpsAgent: agent,
            timeout: 10000
        })
    );
    
    try {
        const results = await Promise.all(promises);
        return {
            statusCode: 200,
            body: JSON.stringify({
                count: results.length,
                data: results.map(r => r.data)
            })
        };
    } catch (error) {
        console.error('Errore:', error.message);
        return {
            statusCode: 500,
            body: JSON.stringify({ error: error.message })
        };
    }
};

3. Caching dei risultati

Se i dati cambiano raramente, memorizza i risultati in DynamoDB o S3:

import boto3
import json
import time

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('proxy-cache')

def get_cached_or_fetch(url, proxies, cache_ttl=3600):
    """Restituisce i dati dalla cache o effettua una richiesta tramite proxy"""
    
    # Controlliamo la cache
    try:
        response = table.get_item(Key={'url': url})
        if 'Item' in response:
            item = response['Item']
            if time.time() - item['timestamp'] < cache_ttl:
                print(f"Cache hit per {url}")
                return item['data']
    except Exception as e:
        print(f"Errore nella cache: {e}")
    
    # Cache vuota o scaduta - effettua la richiesta
    print(f"Cache miss per {url}, fetching...")
    response = requests.get(url, proxies=proxies, timeout=10)
    data = response.text
    
    # Salviamo nella cache
    try:
        table.put_item(Item={
            'url': url,
            'data': data,
            'timestamp': int(time.time())
        })
    except Exception as e:
        print(f"Errore nel salvataggio della cache: {e}")
    
    return data

4. Scegliere il tipo di proxy giusto

Confronto della velocità di diversi tipi di proxy in condizioni reali:

Tipo di proxy Ritardo medio Richieste/minuto (Lambda 1GB RAM) Raccomandazione
Data center 50-200 ms 300-600 Parsing massivo delle API
Residenziali 300-800 ms 100-200 Siti protetti
Mobili 500-1500 ms 50-100 Accesso a contenuti mobili

Conclusione: Scegliere il tipo di proxy giusto è fondamentale per ottimizzare le prestazioni delle funzioni Lambda e garantire un accesso affidabile ai dati.

```