Il proxy restituisce dati errati: cause e soluzioni
Hai configurato lo scraper, avviato la raccolta dati e, come risultato, ottieni prezzi di un'altra regione, contenuti obsoleti o una pagina completamente diversa. Analizziamo perché il proxy potrebbe restituire dati errati e come risolvere il problema.
1. Caching lato proxy
La causa più comune di dati obsoleti è il caching. Alcuni server proxy memorizzano le risposte dei siti web per ridurre il carico e velocizzare le operazioni. Di conseguenza, si ottengono dati vecchi di una settimana invece di quelli attuali.
Come riconoscere il problema
- I dati non cambiano con richieste ripetute
- I prezzi o la disponibilità dei prodotti non corrispondono alla realtà
- L'intestazione
Agenella risposta mostra un valore elevato
Soluzione
Aggiungi intestazioni che vietano il caching:
import requests
headers = {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0'
}
response = requests.get(
'https://example.com/prices',
proxies={'http': proxy, 'https': proxy},
headers=headers
)
Se il provider continua a memorizzare nella cache, aggiungi un parametro casuale all'URL:
import time
url = f'https://example.com/prices?_nocache={int(time.time())}'
2. Disallineamento della geolocalizzazione
Richiedi un proxy dalla Germania e ottieni prezzi in rubli. O viceversa: hai bisogno di dati russi, ma il sito mostra contenuti per gli Stati Uniti. Ciò accade per diverse ragioni.
Perché la geolocalizzazione non corrisponde
| Causa | Descrizione |
|---|---|
| Database GeoIP obsoleti | L'IP si è spostato di recente in una nuova regione, ma i database non sono ancora aggiornati |
| Il sito utilizza il proprio database | Il sito di destinazione determina la posizione geografica in modo diverso rispetto al provider di proxy |
| Cookie della sessione precedente | Il sito ha memorizzato la tua regione dalla visita precedente |
| Accept-Language | L'intestazione della lingua non corrisponde alla posizione geografica del proxy |
Soluzione
Sincronizza tutti i parametri della richiesta con la geolocalizzazione desiderata:
# Per lo scraping di un sito tedesco
headers = {
'Accept-Language': 'de-DE,de;q=0.9,en;q=0.8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)...'
}
# Sessione pulita senza cookie
session = requests.Session()
session.cookies.clear()
response = session.get(
'https://example.de/preise',
proxies={'http': german_proxy, 'https': german_proxy},
headers=headers
)
Prima di eseguire lo scraping, verifica la geolocalizzazione reale dell'IP:
def check_proxy_geo(proxy):
response = requests.get(
'http://ip-api.com/json/',
proxies={'http': proxy, 'https': proxy},
timeout=10
)
data = response.json()
return data.get('country'), data.get('city')
3. Problemi con la rotazione IP
Quando si utilizzano proxy residenziali con rotazione IP automatica, l'indirizzo cambia tra una richiesta e l'altra. Questo è utile per aggirare i limiti, ma crea problemi quando è necessaria la coerenza dei dati.
Sintomi tipici
- La paginazione restituisce duplicati o salta elementi
- Il carrello si svuota tra una richiesta e l'altra
- L'autenticazione viene persa a metà sessione
- I test A/B del sito mostrano versioni diverse delle pagine
Soluzione: sticky sessions
La maggior parte dei provider di proxy supporta le "sticky sessions", che mantengono lo stesso IP per un certo periodo di tempo. Di solito, questo si configura tramite un parametro nella stringa di connessione:
# Esempio di formato con ID sessione (la sintassi dipende dal provider)
proxy = 'http://user-session-abc123:pass@gate.provider.com:7777'
# Tutte le richieste con lo stesso ID sessione passano attraverso lo stesso IP
for page in range(1, 10):
response = requests.get(
f'https://example.com/catalog?page={page}',
proxies={'http': proxy, 'https': proxy}
)
Importante: Una sticky session dura generalmente da 1 a 30 minuti. Pianifica la raccolta dati in modo che le richieste correlate rientrino in questa finestra.
4. Violazione di sessioni e cookie
I siti moderni utilizzano attivamente i cookie per la personalizzazione. Se il tuo scraper non li gestisce correttamente, otterrai dati errati o verrai bloccato del tutto.
Errori comuni
- Ignorare Set-Cookie — il sito non può tracciare la sessione
- Riutilizzo di cookie con un IP diverso — comportamento sospetto
- Assenza di una richiesta iniziale — accesso diretto a una pagina interna senza un "accesso" tramite la homepage
Approccio corretto
import requests
def create_browser_session(proxy):
session = requests.Session()
session.proxies = {'http': proxy, 'https': proxy}
# Simula la prima visita — ottieni i cookie
session.get('https://example.com/', headers={
'User-Agent': 'Mozilla/5.0...',
'Accept': 'text/html,application/xhtml+xml...',
'Accept-Language': 'en-US,en;q=0.9'
})
# Ora puoi eseguire lo scraping con una sessione valida
return session
session = create_browser_session(proxy)
data = session.get('https://example.com/api/prices').json()
5. Errori di codifica e compressione
A volte i dati arrivano corretti, ma vengono visualizzati in modo errato a causa di problemi di codifica o compressione. Questo è particolarmente rilevante quando si lavora con caratteri cirillici e lingue asiatiche.
Sintomi
- Caratteri incomprensibili al posto del testo:
Ценаinvece di «Prezzo» - Risposta vuota con gzip abilitato
- Spazzatura binaria invece di HTML
Soluzione
import requests
response = requests.get(url, proxies=proxies)
# Metodo 1: Rilevamento automatico della codifica
response.encoding = response.apparent_encoding
text = response.text
# Metodo 2: Codifica forzata
text = response.content.decode('utf-8')
# Metodo 3: Disabilitare la compressione (se il proxy danneggia gzip)
headers = {'Accept-Encoding': 'identity'}
response = requests.get(url, proxies=proxies, headers=headers)
6. Blocchi nascosti e CAPTCHA
Non tutti i blocchi sono ovvi. Un sito può restituire HTTP 200, ma invece dei dati reali, fornire una pagina segnaposto, una cache obsoleta o una pagina con CAPTCHA all'interno dell'HTML standard.
Segnali di blocco nascosto
- La dimensione della risposta è sospettosamente piccola o identica per pagine diverse
- L'HTML contiene le parole: captcha, challenge, blocked, access denied
- Mancano gli elementi attesi (prezzi, descrizioni, pulsanti)
- Reindirizzamento JavaScript a un'altra pagina
Validazione della risposta
def is_valid_response(response, expected_markers):
"""Verifica che la risposta contenga dati reali"""
text = response.text.lower()
# Controllo del blocco
block_signals = ['captcha', 'blocked', 'access denied',
'rate limit', 'try again later']
for signal in block_signals:
if signal in text:
return False, f'Bloccato: {signal}'
# Controllo della presenza dei dati attesi
for marker in expected_markers:
if marker.lower() not in text:
return False, f'Mancante: {marker}'
# Controllo della dimensione (troppo piccola = segnaposto)
if len(response.content) < 5000:
return False, 'Risposta troppo piccola'
return True, 'OK'
# Utilizzo
valid, reason = is_valid_response(response, ['price', 'add to cart'])
if not valid:
print(f'Risposta non valida: {reason}')
# Cambia proxy, attendi, riprova
Per i siti con una protezione anti-bot seria, i proxy mobili offrono un livello di fiducia migliore rispetto a quelli datacenter.
7. Diagnostica passo passo
Quando un proxy restituisce dati errati, utilizza questo algoritmo per trovare la causa:
Passo 1: Isolare il problema
# Confronta le risposte: senza proxy vs con proxy
def compare_responses(url, proxy):
direct = requests.get(url)
proxied = requests.get(url, proxies={'http': proxy, 'https': proxy})
print(f'Diretto: {len(direct.content)} byte, stato {direct.status_code}')
print(f'Proxy: {len(proxied.content)} byte, stato {proxied.status_code}')
# Salva entrambe le risposte per il confronto
with open('direct.html', 'w') as f:
f.write(direct.text)
with open('proxied.html', 'w') as f:
f.write(proxied.text)
Passo 2: Controlla le intestazioni di risposta
response = requests.get(url, proxies=proxies)
# Intestazioni chiave per la diagnostica
important_headers = ['content-type', 'content-encoding',
'cache-control', 'age', 'x-cache',
'cf-ray', 'server']
for header in important_headers:
value = response.headers.get(header, 'non impostato')
print(f'{header}: {value}')
Passo 3: Lista di controllo delle verifiche
| Verifica | Comando/Metodo |
|---|---|
| IP reale del proxy | curl -x proxy:port ifconfig.me |
| Geolocalizzazione IP | ip-api.com/json |
| Caching | Intestazioni Age, X-Cache |
| Blocco | Ricerca di «captcha», «blocked» nell'HTML |
| Codifica | Content-Type charset |
Passo 4: Script di diagnostica completo
import requests
import json
def diagnose_proxy(proxy, target_url):
report = {}
# 1. Verifica della funzionalità
try:
r = requests.get('http://httpbin.org/ip',
proxies={'http': proxy, 'https': proxy},
timeout=15)
report['proxy_ip'] = r.json().get('origin')
report['proxy_works'] = True
except Exception as e:
report['proxy_works'] = False
report['error'] = str(e)
return report
# 2. Geolocalizzazione
r = requests.get('http://ip-api.com/json/',
proxies={'http': proxy, 'https': proxy})
geo = r.json()
report['country'] = geo.get('country')
report['city'] = geo.get('city')
# 3. Richiesta al sito di destinazione
r = requests.get(target_url,
proxies={'http': proxy, 'https': proxy},
timeout=30)
report['status_code'] = r.status_code
report['content_length'] = len(r.content)
report['cached'] = 'age' in r.headers or 'x-cache' in r.headers
# 4. Controllo del blocco
block_words = ['captcha', 'blocked', 'denied', 'cloudflare']
report['possibly_blocked'] = any(w in r.text.lower() for w in block_words)
return report
# Utilizzo
result = diagnose_proxy('http://user:pass@proxy:port', 'https://target-site.com')
print(json.dumps(result, indent=2))
Conclusione
Dati errati provenienti da un proxy sono quasi sempre un problema risolvibile. Nella maggior parte dei casi, la causa è legata al caching, al disallineamento della geolocalizzazione o alla gestione errata delle sessioni. Utilizza lo script di diagnostica in questo articolo per identificare rapidamente la fonte del problema.
Per attività in cui la precisione della geolocalizzazione e una bassa percentuale di blocchi sono fondamentali, i proxy residenziali con supporto per sticky sessions sono la scelta ottimale: maggiori dettagli su proxycove.com.