Watch-IP

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