Geolocalizzazione IP in batch con Python
Arricchisci un elenco di IP tramite POST /v1/lookup in batch da 100, con associazione alla riga di origine, output con checkpoint e backoff sui 429 — chiamato direttamente via HTTP, poiché l'SDK Python ufficiale non copre questo endpoint.
Prima di iniziare
- Un account Watch-IP e una chiave segreta di ricerca — POST /v1/lookup è solo da server a server; non chiamarlo mai da un browser né distribuire la chiave in un client.
- Python 3.9+.
- Un elenco locale di IP da arricchire — questa guida li legge da un CSV con un IP per riga.
1. Perché si usa l'HTTP diretto invece dell'SDK
watch-ip-sdk, il pacchetto Python ufficiale, implementa solo GET /v1/geo, l'endpoint visitatore rivolto al browser — non ha alcun metodo per POST /v1/lookup. Questa guida chiama l'API direttamente con urllib dalla libreria standard, seguendo lo stesso approccio a zero dipendenze dell'SDK invece di aggiungerne una nuova solo per questo.
2. Leggi e convalida l'elenco di input
Mantieni la posizione originale di riga di ciascun IP, così un risultato può essere ricollegato al record da cui proviene — l'API restituisce i risultati nello stesso ordine in cui ha ricevuto gli IP, il che è utile solo se anche il tuo elenco resta in quell'ordine.
Python
import csv
with open("ips.csv", newline="") as f:
ips = [row[0].strip() for row in csv.reader(f) if row and row[0].strip()]
print(f"Loaded {len(ips)} IPs")3. Dividi in batch da 100
POST /v1/lookup accetta da 1 a 100 IP per chiamata e convalida l'intero batch prima di effettuare qualsiasi ricerca — un indirizzo malformato fa fallire l'intero blocco, quindi convalida prima localmente la sintassi degli IP se il tuo elenco di input potrebbe non essere pulito.
Python
def chunk(items, size=100):
for i in range(0, len(items), size):
yield items[i : i + size]4. Invia ogni batch e salva un checkpoint dei risultati
Scrivi i risultati man mano che ogni batch si completa invece di tenere tutto in memoria fino alla fine, così un errore a metà di un elenco lungo non fa perdere i batch già riusciti. found: false significa che l'IP è sintatticamente valido ma non ha una voce nel database — un risultato normale, non un errore.
Python
import json
import time
import urllib.error
import urllib.request
API_URL = "https://api.watch-ip.com/v1/lookup"
SECRET_KEY = "YOUR_SECRET_KEY"
def lookup_batch(ips):
request = urllib.request.Request(
API_URL,
data=json.dumps({"ips": ips}).encode(),
headers={
"Authorization": f"Bearer {SECRET_KEY}",
"Content-Type": "application/json",
},
)
with urllib.request.urlopen(request) as response:
return json.load(response)["results"]
with open("results.jsonl", "a") as out:
for batch in chunk(ips):
try:
results = lookup_batch(batch)
except urllib.error.HTTPError as err:
if err.code == 429:
time.sleep(60) # attendi il resto della finestra di un minuto in corso
results = lookup_batch(batch)
else:
raise
for result in results:
out.write(json.dumps(result) + "\n")5. Riprendere un lavoro parziale
Poiché i risultati vengono aggiunti un batch alla volta, riavviare dopo un crash richiede solo di saltare gli IP già scritti in results.jsonl invece di reinviare l'intero elenco — reinviare un IP duplicato viene fatturato di nuovo, poiché ogni input di un batch viene misurato individualmente e non deduplicato.
Python
done = set()
with open("results.jsonl") as f:
for line in f:
done.add(json.loads(line)["ip"])
remaining = [ip for ip in ips if ip not in done]Errori e casi limite
Un 400 significa che il batch aveva più di 100 IP, un elenco vuoto, oppure un indirizzo malformato al suo interno — fallisce l'intero blocco, non solo la voce errata. Un 403 significa che è stata usata una chiave pubblicabile invece di una chiave segreta. Mischiare indirizzi IPv4 e IPv6 nello stesso batch va bene; ciascuno viene cercato in modo indipendente, con gli stessi campi nullable in entrambi i casi.
Passo successivo
Consulta il riferimento della ricerca IP in blocco per lo schema esatto della risposta, ed errori e limiti di frequenza per l'elenco completo dei codici di stato che questo endpoint può restituire.
Pagine correlate
- Ricerca IP in bloccoRisolvi fino a 100 indirizzi IP forniti in un'unica richiesta backend.
- Riferimento POST /v1/lookupRiferimento completo dei campi per l'endpoint di ricerca IP in blocco.
- SDK Pythonwatch-ip-sdk su PyPI.
- Errori e limiti di frequenzaFormato della risposta di errore, codici di stato e indicazioni per i tentativi.