Geolocalização de IP em lote com Python
Enriqueça uma lista de IPs através de POST /v1/lookup em lotes de 100, com associação por linha, saída com pontos de verificação, e recuo em caso de 429 — chamado diretamente via HTTP, uma vez que o SDK oficial de Python não cobre este endpoint.
Antes de começar
- Uma conta Watch-IP e uma chave secreta de pesquisa — POST /v1/lookup é apenas servidor-a-servidor; nunca o chame a partir de um navegador nem distribua a chave num cliente.
- Python 3.9+.
- Uma lista local de IPs a enriquecer — este guia lê-os a partir de um CSV com um IP por linha.
1. Porque é que isto utiliza HTTP direto em vez do SDK
watch-ip-sdk, o pacote oficial de Python, implementa apenas GET /v1/geo, o endpoint de visitante voltado para o navegador — não tem qualquer método para POST /v1/lookup. Este guia chama a API diretamente com urllib da biblioteca padrão, seguindo a própria abordagem de zero dependências do SDK em vez de acrescentar uma nova apenas para isto.
2. Leia e valide a lista de entrada
Mantenha a posição de linha original de cada IP para que um resultado possa ser associado de novo ao registo de onde veio — a API devolve resultados pela mesma ordem em que recebeu os IPs, o que só ajuda se a sua própria lista também mantiver essa ordem.
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"{len(ips)} IPs carregados")3. Divida em lotes de 100
POST /v1/lookup aceita entre 1 e 100 IPs por chamada e valida todo o lote antes de pesquisar seja o que for — um endereço mal formado faz falhar o lote inteiro, por isso valide a sintaxe dos IPs localmente primeiro, caso a sua lista de entrada possa estar suja.
Python
def chunk(items, size=100):
for i in range(0, len(items), size):
yield items[i : i + size]4. Envie cada lote e guarde pontos de verificação dos resultados
Escreva os resultados à medida que cada lote é concluído, em vez de manter tudo em memória até ao fim, para que uma falha a meio de uma lista longa não perca os lotes já bem-sucedidos. found: false significa que o IP é sintaticamente válido mas não tem entrada na base de dados — um resultado normal, não um erro.
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) # aguardar até ao fim da janela de um minuto atual
results = lookup_batch(batch)
else:
raise
for result in results:
out.write(json.dumps(result) + "\n")5. Retomar um trabalho parcial
Uma vez que os resultados são acrescentados um lote de cada vez, reiniciar após uma falha só precisa de ignorar os IPs já escritos em results.jsonl, em vez de reenviar a lista inteira — reenviar um IP duplicado é faturado de novo, uma vez que cada entrada de um lote é medida individualmente e não deduplicada.
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]Erros e casos limite
Um 400 significa que o lote tinha mais de 100 IPs, uma lista vazia, ou um endereço mal formado nalgum ponto — o lote inteiro falha, não apenas a entrada errada. Um 403 significa que foi utilizada uma chave publicável em vez de uma chave secreta. Misturar endereços IPv4 e IPv6 no mesmo lote não é problema; cada um é pesquisado de forma independente, com os mesmos campos anuláveis em ambos os casos.
Próximo passo
Consulte a referência de pesquisa de IP em lote para o esquema exato da resposta, e erros e limites de taxa para a lista completa de códigos de estado que este endpoint pode devolver.
Páginas relacionadas
- Pesquisa de IP em loteResolva até 100 endereços IP fornecidos num único pedido de back-end.
- Referência de POST /v1/lookupReferência completa de campos para o endpoint de pesquisa de IP em lote.
- SDK de Pythonwatch-ip-sdk no PyPI.
- Erros e limites de taxaForma da resposta de erro, códigos de estado, e orientação sobre novas tentativas.