OSINT com Python: automatizando coleta e enriquecimento
Chega um momento em que o investigador OSINT precisa escalar: consultar dezenas de APIs, raspar paginas, cruzar resultados. Fazer isso na mao e lento e sujeito a erro. Python resolve. Com poucas bibliotecas voce automatiza a coleta, enriquece dados e prepara tudo para analise. Este guia mostra o essencial com codigo funcional e comentado, alem das boas praticas que separam um script amador de uma ferramenta confiavel.
Por que Python para OSINT?
Python domina o OSINT por tres motivos: sintaxe simples, ecossistema enorme de bibliotecas e integracao facil com APIs. A pilha minima viavel e requests + BeautifulSoup + pandas + python-dotenv. Com ela voce faz requisicoes HTTP, parseia HTML, organiza dados em tabelas e protege suas chaves de API.
Instale a base:
pip install requests beautifulsoup4 pandas python-dotenv
Fazendo requisicoes com requests
A biblioteca requests envia requisicoes HTTP. O padrao basico:
import requests
# Sempre defina um User-Agent honesto e um timeout
headers = {"User-Agent": "OsintHunters-Pesquisa/1.0"}
resposta = requests.get(
"https://api.exemplo.com/dados",
headers=headers,
timeout=10 # evita travar para sempre em um servidor lento
)
# Levanta excecao se o status for 4xx ou 5xx
resposta.raise_for_status()
print(resposta.status_code) # 200 significa sucesso
Tres detalhes importantes nesse bloco: o timeout impede travamentos, o raise_for_status() transforma erros HTTP em excecoes trataveis, e o User-Agent identifica seu script de forma transparente.
Consumindo APIs e lidando com JSON
A maioria das fontes modernas expoe APIs que retornam JSON. Exemplo consultando a API publica do GitHub para enriquecer um nome de usuario:
import requests
def enriquecer_usuario_github(usuario):
url = f"https://api.github.com/users/{usuario}"
r = requests.get(url, timeout=10)
if r.status_code == 404:
return None # usuario nao existe
r.raise_for_status()
dados = r.json() # converte a resposta JSON em dicionario Python
# Extrai apenas os campos de interesse
return {
"login": dados.get("login"),
"nome": dados.get("name"),
"empresa": dados.get("company"),
"repos_publicos": dados.get("public_repos"),
"criado_em": dados.get("created_at"),
}
perfil = enriquecer_usuario_github("torvalds")
print(perfil)
Repare no uso de dados.get("campo") em vez de dados["campo"]: o .get() devolve None se a chave nao existir, evitando que o script quebre com um KeyError.
Protegendo chaves de API
Nunca escreva chaves direto no codigo. Use variaveis de ambiente com python-dotenv. Crie um arquivo .env:
API_KEY=sua_chave_secreta_aqui
E no script:
import os
from dotenv import load_dotenv
load_dotenv() # le o arquivo .env
chave = os.getenv("API_KEY")
headers = {"Authorization": f"Bearer {chave}"}
Lembre de adicionar .env ao .gitignore para nao vazar segredos em repositorios.
Parsing de HTML com BeautifulSoup
Nem toda fonte tem API. Quando so ha HTML, o requests baixa a pagina e o BeautifulSoup extrai os dados. O requests envia a requisicao e o BeautifulSoup parseia o conteudo HTML, criando uma arvore navegavel.
import requests
from bs4 import BeautifulSoup
url = "https://exemplo.com.br/pagina"
r = requests.get(url, timeout=10)
r.raise_for_status()
# Cria a arvore de parsing
sopa = BeautifulSoup(r.text, "html.parser")
# Extrai o titulo da pagina
print(sopa.title.string)
# Pega todos os links
for link in sopa.find_all("a"):
href = link.get("href")
if href:
print(href)
# Busca por classe CSS especifica
for item in sopa.select("div.resultado h3"):
print(item.get_text(strip=True))
O metodo select() aceita seletores CSS, o jeito mais pratico de mirar elementos especificos. O get_text(strip=True) extrai o texto limpo, sem espacos sobrando.
Juntando tudo: coleta e enriquecimento em lote
O verdadeiro ganho vem ao processar muitos alvos e organizar o resultado. Exemplo que enriquece uma lista de usuarios e salva em CSV com pandas:
import requests
import pandas as pd
import time
def enriquecer(usuario):
url = f"https://api.github.com/users/{usuario}"
try:
r = requests.get(url, timeout=10)
r.raise_for_status()
d = r.json()
return {
"usuario": usuario,
"nome": d.get("name"),
"repos": d.get("public_repos"),
"seguidores": d.get("followers"),
}
except requests.RequestException as e:
# Registra a falha sem derrubar o lote inteiro
return {"usuario": usuario, "erro": str(e)}
alvos = ["torvalds", "gvanrossum", "mojombo"]
resultados = []
for alvo in alvos:
resultados.append(enriquecer(alvo))
time.sleep(1) # respeita a API: 1 segundo entre chamadas
# Monta um DataFrame e exporta
df = pd.DataFrame(resultados)
df.to_csv("enriquecimento.csv", index=False, encoding="utf-8")
print(df)
Dois pontos de boa pratica aqui: o try/except requests.RequestException isola falhas de rede para que um alvo problematico nao derrube o lote, e o time.sleep(1) espaca as chamadas para nao abusar da fonte.
Boas praticas de automacao OSINT
- Respeite limites de taxa (rate limit). Insira pausas e trate o status HTTP 429 (muitas requisicoes). Scripts agressivos sao bloqueados e sobrecarregam servidores alheios.
- Trate erros sempre. Rede falha, APIs mudam, paginas somem. Use
try/excepte registre o que der errado. - Cacheie resultados. Se ja consultou um alvo, salve. Evita refazer requisicoes e poupa a fonte.
- Escolha a ferramenta certa. Para trabalho de escala investigativa (menos de mil paginas),
requests+BeautifulSoupcostuma ser mais rapido de escrever; o Scrapy compensa acima desse volume. - Leia o robots.txt e os termos. Respeitar as regras do site e parte da conduta profissional.
- Documente a procedencia. Salve URL, data e hora de cada coleta para garantir rastreabilidade.
Armadilhas comuns
- Acessar
json()sem checar o status: se a resposta for erro, o conteudo nao sera o JSON esperado. - Hardcodar chaves de API: risco de vazamento. Use
.env. - Ignorar encoding: forcar
encoding="utf-8"evita acentos corrompidos no CSV. - Loop sem pausa: dispara centenas de requisicoes por segundo e leva a bloqueio.
Etica e legalidade
Automatizar coleta amplia seu alcance e tambem sua responsabilidade. Use somente fontes abertas e publicas, respeite os termos de uso e o robots.txt dos sites e nao tente contornar autenticacao ou controles de acesso. No Brasil, dados pessoais coletados ficam sob a LGPD: colete o minimo, com finalidade legitima, e proteja o que armazenar. O Marco Civil da Internet reforca a privacidade dos usuarios. Automacao responsavel e a marca do profissional serio.
Conclusao
Com requests, consumo de APIs, BeautifulSoup e pandas, voce monta pipelines de coleta e enriquecimento que escalam sua investigacao sem perder o controle. Comece pequeno, trate erros, respeite as fontes e evolua. Construiu um script OSINT util? Compartilhe seu codigo e troque ideias com a comunidade OsintHunters Brasil.
