Batchgewijze IP-geolocatie met Python
Verrijk een lijst met IP's via POST /v1/lookup in batches van 100, met koppeling per rij, tussentijds opgeslagen resultaten en 429-backoff — rechtstreeks over HTTP aangeroepen, aangezien de officiële Python SDK dit endpoint niet dekt.
Voordat je begint
- Een Watch-IP-account en een geheime lookup-sleutel — POST /v1/lookup is alleen server-naar-server; roep het nooit aan vanuit een browser en verstuur de sleutel nooit in een client.
- Python 3.9+.
- Een lokale lijst met IP's om te verrijken — deze handleiding leest ze uit een CSV met één IP per regel.
1. Waarom dit rechtstreeks HTTP gebruikt in plaats van de SDK
watch-ip-sdk, het officiële Python-pakket, implementeert alleen GET /v1/geo, het browsergerichte bezoekersendpoint — het heeft geen methode voor POST /v1/lookup. Deze handleiding roept de API rechtstreeks aan met urllib uit de standaardbibliotheek, wat aansluit bij de eigen aanpak zonder afhankelijkheden van de SDK, in plaats van er speciaal voor deze handleiding een nieuwe afhankelijkheid bij te halen.
2. De invoerlijst lezen en valideren
Houd de oorspronkelijke rijpositie van elk IP bij, zodat een resultaat kan worden teruggekoppeld aan het record waar het vandaan kwam — de API geeft resultaten terug in dezelfde volgorde als waarin de IP's zijn ontvangen, wat alleen helpt als je eigen lijst ook in die volgorde blijft staan.
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. Opsplitsen in batches van 100
POST /v1/lookup accepteert 1–100 IP's per aanroep en valideert de hele batch voordat er iets wordt opgezocht — één onjuist geformatteerd adres laat het hele blok mislukken, dus valideer de IP-syntaxis eerst lokaal als je invoerlijst mogelijk niet schoon is.
Python
def chunk(items, size=100):
for i in range(0, len(items), size):
yield items[i : i + size]4. Elke batch versturen en resultaten tussentijds opslaan
Schrijf resultaten weg zodra elke batch is afgerond, in plaats van alles tot het einde in het geheugen te houden, zodat een fout halverwege een lange lijst niet de batches verliest die al zijn geslaagd. found: false betekent dat het IP syntactisch geldig is maar geen record in de database heeft — een normaal resultaat, geen fout.
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) # wacht de rest van het huidige venster van één minuut af
results = lookup_batch(batch)
else:
raise
for result in results:
out.write(json.dumps(result) + "\n")5. Een gedeeltelijke taak hervatten
Omdat resultaten telkens één batch tegelijk worden toegevoegd, hoeft een herstart na een crash alleen de IP's over te slaan die al naar results.jsonl zijn geschreven, in plaats van de hele lijst opnieuw in te dienen — een dubbel ingediend IP wordt opnieuw in rekening gebracht, omdat elke invoer in een batch afzonderlijk wordt gemeten in plaats van gededupliceerd.
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]Foutmeldingen en randgevallen
Een 400 betekent dat de batch meer dan 100 IP's bevatte, een lege lijst was, of ergens een onjuist geformatteerd adres bevatte — het hele blok mislukt, niet alleen de foutieve invoer. Een 403 betekent dat er een publiceerbare sleutel is gebruikt in plaats van een geheime sleutel. Gemengde IPv4- en IPv6-adressen in dezelfde batch zijn geen probleem; elk wordt onafhankelijk opgezocht, met in beide gevallen dezelfde nullable velden.
Volgende stap
Zie de referentie voor bulk IP-lookup voor het exacte antwoordschema, en foutmeldingen en rate limits voor de volledige lijst statuscodes die dit endpoint kan teruggeven.