Ao desenvolver aplicações Node.js para scraping, automação ou trabalho com APIs, frequentemente surge a necessidade de utilizar servidores proxy. Isso permite contornar restrições geográficas, distribuir a carga e evitar bloqueios por IP. Neste guia, abordaremos todas as formas de configurar proxies em Node.js — desde técnicas básicas até avançadas com rotação e tratamento de erros.
Conceitos básicos de trabalho com proxy em Node.js
Um servidor proxy em Node.js funciona como um intermediário entre sua aplicação e o servidor de destino. Quando você envia uma solicitação HTTP através de um proxy, sua aplicação primeiro se conecta ao servidor proxy, que então redireciona a solicitação para o endereço final. Isso permite ocultar o verdadeiro endereço IP do seu servidor e usar o endereço IP do proxy.
Em Node.js, existem várias maneiras principais de trabalhar com proxies, dependendo da biblioteca utilizada para solicitações HTTP. As opções mais populares incluem:
- Módulos embutidos http/https — funcionalidade básica sem dependências adicionais
- Axios — biblioteca popular com uma API conveniente e suporte a promessas
- Got — alternativa moderna com suporte a TypeScript
- node-fetch — implementação da Fetch API para Node.js
- request — biblioteca obsoleta, mas ainda utilizada (não recomendada para novos projetos)
Os servidores proxy suportam vários protocolos. Para trabalhar com Node.js, os mais utilizados são:
| Protocolo | Descrição | Aplicação |
|---|---|---|
| HTTP | Protocolo básico para conexões não criptografadas | Scraping, trabalho com API sem SSL |
| HTTPS | Proxy com suporte a criptografia SSL/TLS | Conexões seguras, trabalho com APIs protegidas |
| SOCKS5 | Protocolo universal para qualquer tipo de tráfego | WebSocket, UDP, cenários complexos |
Para tarefas de scraping e automação, os desenvolvedores frequentemente utilizam proxies residenciais, pois eles possuem endereços IP reais de usuários domésticos e raramente são bloqueados por sites de destino.
Configuração de proxy através do módulo http/https embutido
O Node.js fornece módulos embutidos http e https para trabalhar com solicitações HTTP. Para conectar um proxy, você pode usar a biblioteca http-proxy-agent ou https-proxy-agent.
Primeiro, instale os pacotes necessários:
npm install http-proxy-agent https-proxy-agent
Exemplo de uso de proxy HTTP com o módulo embutido:
const http = require('http');
const { HttpProxyAgent } = require('http-proxy-agent');
// Configurações do proxy
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = new HttpProxyAgent(proxyUrl);
// Opções da solicitação
const options = {
hostname: 'api.example.com',
path: '/endpoint',
method: 'GET',
agent: agent,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
};
// Execução da solicitação
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Resposta:', data);
});
});
req.on('error', (error) => {
console.error('Solicitação falhou:', error.message);
});
req.end();
Para conexões HTTPS, use https-proxy-agent:
const https = require('https');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);
const options = {
hostname: 'api.example.com',
path: '/secure-endpoint',
method: 'GET',
agent: agent
};
https.get(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Resposta segura:', data);
});
}).on('error', (error) => {
console.error('Solicitação HTTPS falhou:', error.message);
});
Essa abordagem oferece controle máximo sobre as solicitações, mas requer mais código para tratamento de promessas e erros. Para a maioria das tarefas, é mais conveniente usar bibliotecas especializadas.
Trabalho com proxy na biblioteca Axios
Axios é uma das bibliotecas mais populares para solicitações HTTP em Node.js. Ela fornece uma API conveniente para configuração de proxy e trata automaticamente as promessas.
Instalação do Axios:
npm install axios
A configuração básica de proxy no Axios é a seguinte:
const axios = require('axios');
// Método 1: Configuração de proxy na configuração da solicitação
axios.get('https://api.example.com/data', {
proxy: {
protocol: 'http',
host: 'proxy-server.com',
port: 8080,
auth: {
username: 'your-username',
password: 'your-password'
}
}
})
.then(response => {
console.log('Dados:', response.data);
})
.catch(error => {
console.error('Erro:', error.message);
});
Para reutilizar as mesmas configurações de proxy, é conveniente criar uma instância do Axios com a configuração pré-definida:
const axios = require('axios');
// Criação de instância com configurações de proxy
const axiosWithProxy = axios.create({
proxy: {
protocol: 'http',
host: 'proxy-server.com',
port: 8080,
auth: {
username: 'your-username',
password: 'your-password'
}
},
timeout: 10000,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
});
// Uso da instância
async function fetchData() {
try {
const response = await axiosWithProxy.get('https://api.example.com/data');
console.log('Resposta:', response.data);
return response.data;
} catch (error) {
console.error('Solicitação falhou:', error.message);
throw error;
}
}
fetchData();
Para trabalhar com proxy HTTPS através do método CONNECT, você pode usar agentes adicionais:
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const httpsAgent = new HttpsProxyAgent(proxyUrl);
const axiosInstance = axios.create({
httpsAgent: httpsAgent,
timeout: 15000
});
// Uso
axiosInstance.get('https://api.example.com/secure-data')
.then(response => console.log(response.data))
.catch(error => console.error(error.message));
O Axios lida automaticamente com redirecionamentos e suporta interceptadores para registro e tratamento de erros, tornando-o uma excelente escolha para projetos que utilizam intensivamente proxies.
Configuração de proxy em got e node-fetch
Got é uma alternativa moderna ao Axios com excelente suporte a TypeScript e recursos avançados de tratamento de erros. O node-fetch implementa a Fetch API padrão para Node.js.
Trabalho com proxy em Got
Instalação do Got e dos agentes necessários:
npm install got https-proxy-agent
Exemplo de configuração de proxy no Got:
const got = require('got');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = {
https: new HttpsProxyAgent(proxyUrl)
};
// Criação de instância Got com proxy
const gotWithProxy = got.extend({
agent: agent,
timeout: {
request: 10000
},
retry: {
limit: 3,
methods: ['GET', 'POST']
}
});
// Uso
async function fetchWithGot() {
try {
const response = await gotWithProxy('https://api.example.com/data');
console.log('Resposta:', JSON.parse(response.body));
} catch (error) {
console.error('Solicitação Got falhou:', error.message);
}
}
fetchWithGot();
Trabalho com proxy em node-fetch
O node-fetch requer configuração explícita do agente para trabalhar com proxy:
npm install node-fetch https-proxy-agent
const fetch = require('node-fetch');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = 'http://username:password@proxy-server.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);
async function fetchWithProxy() {
try {
const response = await fetch('https://api.example.com/data', {
agent: agent,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
}
});
if (!response.ok) {
throw new Error(`Erro HTTP! status: ${response.status}`);
}
const data = await response.json();
console.log('Dados:', data);
return data;
} catch (error) {
console.error('Fetch falhou:', error.message);
throw error;
}
}
fetchWithProxy();
O Got oferece uma funcionalidade mais rica fora da caixa (repetições automáticas, timeouts, tratamento de erros), enquanto o node-fetch é mais próximo da Fetch API padrão e é adequado para desenvolvedores familiarizados com JavaScript de navegador.
Conexão de proxy SOCKS5 através do socks-proxy-agent
SOCKS5 é um protocolo de proxy universal que opera em um nível mais baixo do que HTTP/HTTPS. Ele suporta qualquer tipo de tráfego, incluindo conexões UDP e WebSocket. Para trabalhar com SOCKS5 em Node.js, utiliza-se a biblioteca socks-proxy-agent.
Instalação dos pacotes necessários:
npm install socks-proxy-agent
Exemplo de uso de proxy SOCKS5 com várias bibliotecas:
const { SocksProxyAgent } = require('socks-proxy-agent');
const https = require('https');
// Configuração de proxy SOCKS5 com autenticação
const proxyUrl = 'socks5://username:password@proxy-server.com:1080';
const agent = new SocksProxyAgent(proxyUrl);
const options = {
hostname: 'api.example.com',
path: '/endpoint',
method: 'GET',
agent: agent
};
https.get(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Resposta SOCKS5:', data);
});
}).on('error', (error) => {
console.error('Solicitação SOCKS5 falhou:', error.message);
});
Uso de SOCKS5 com Axios:
const axios = require('axios');
const { SocksProxyAgent } = require('socks-proxy-agent');
const proxyUrl = 'socks5://username:password@proxy-server.com:1080';
const httpsAgent = new SocksProxyAgent(proxyUrl);
const httpAgent = new SocksProxyAgent(proxyUrl);
const axiosWithSocks = axios.create({
httpAgent: httpAgent,
httpsAgent: httpsAgent,
timeout: 15000
});
async function fetchViaSocks5() {
try {
const response = await axiosWithSocks.get('https://api.example.com/data');
console.log('Dados via SOCKS5:', response.data);
return response.data;
} catch (error) {
console.error('Erro na solicitação SOCKS5:', error.message);
throw error;
}
}
fetchViaSocks5();
Proxies SOCKS5 são especialmente úteis para tarefas que requerem trabalho com protocolos não padrão ou quando é necessária máxima flexibilidade. Muitos provedores oferecem proxies móveis com suporte a SOCKS5, permitindo emular tráfego móvel para trabalhar com APIs móveis.
Implementação de rotação de proxy para distribuição de carga
Ao fazer scraping de grandes volumes de dados ou trabalhar com APIs que têm limites de solicitações de um único IP, é necessário usar rotação de proxies. Isso permite distribuir as solicitações entre vários servidores proxy e evitar bloqueios.
Exemplo de implementação de uma rotação simples de proxies:
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
class ProxyRotator {
constructor(proxyList) {
this.proxyList = proxyList;
this.currentIndex = 0;
}
// Obter o próximo proxy de forma circular
getNextProxy() {
const proxy = this.proxyList[this.currentIndex];
this.currentIndex = (this.currentIndex + 1) % this.proxyList.length;
return proxy;
}
// Obter um proxy aleatório
getRandomProxy() {
const randomIndex = Math.floor(Math.random() * this.proxyList.length);
return this.proxyList[randomIndex];
}
// Criar uma instância do Axios com o proxy atual
createAxiosInstance(useRandom = false) {
const proxyUrl = useRandom ? this.getRandomProxy() : this.getNextProxy();
const agent = new HttpsProxyAgent(proxyUrl);
return axios.create({
httpsAgent: agent,
timeout: 10000,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
});
}
}
// Lista de proxies
const proxyList = [
'http://user1:pass1@proxy1.example.com:8080',
'http://user2:pass2@proxy2.example.com:8080',
'http://user3:pass3@proxy3.example.com:8080',
'http://user4:pass4@proxy4.example.com:8080'
];
const rotator = new ProxyRotator(proxyList);
// Uso da rotação
async function fetchWithRotation(url) {
const axiosInstance = rotator.createAxiosInstance();
try {
const response = await axiosInstance.get(url);
console.log('Sucesso com proxy');
return response.data;
} catch (error) {
console.error('Solicitação falhou:', error.message);
throw error;
}
}
// Exemplo de scraping em massa com rotação
async function massiveParsing(urls) {
const results = [];
for (const url of urls) {
try {
const data = await fetchWithRotation(url);
results.push({ url, success: true, data });
// Atraso entre solicitações
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
results.push({ url, success: false, error: error.message });
}
}
return results;
}
// Iniciar o scraping
const urlsToParse = [
'https://api.example.com/data/1',
'https://api.example.com/data/2',
'https://api.example.com/data/3',
'https://api.example.com/data/4',
'https://api.example.com/data/5'
];
massiveParsing(urlsToParse)
.then(results => console.log('Resultados do scraping:', results))
.catch(error => console.error('Erro no scraping:', error));
Um exemplo mais avançado com monitoramento do estado do proxy e exclusão automática de proxies não funcionais:
class AdvancedProxyRotator {
constructor(proxyList, maxFailures = 3) {
this.proxyList = proxyList.map(url => ({
url,
failures: 0,
active: true,
lastUsed: null
}));
this.maxFailures = maxFailures;
this.currentIndex = 0;
}
// Obter um proxy ativo
getActiveProxy() {
const activeProxies = this.proxyList.filter(p => p.active);
if (activeProxies.length === 0) {
throw new Error('Nenhum proxy ativo disponível');
}
// Encontrar o proxy que não foi usado há mais tempo
const proxy = activeProxies.reduce((oldest, current) => {
if (!oldest.lastUsed) return oldest;
if (!current.lastUsed) return current;
return current.lastUsed < oldest.lastUsed ? current : oldest;
});
proxy.lastUsed = Date.now();
return proxy;
}
// Marcar proxy como bem-sucedido
markSuccess(proxyUrl) {
const proxy = this.proxyList.find(p => p.url === proxyUrl);
if (proxy) {
proxy.failures = 0;
}
}
// Marcar proxy como falho
markFailure(proxyUrl) {
const proxy = this.proxyList.find(p => p.url === proxyUrl);
if (proxy) {
proxy.failures++;
if (proxy.failures >= this.maxFailures) {
proxy.active = false;
console.warn(`Proxy ${proxyUrl} desativado após ${proxy.failures} falhas`);
}
}
}
// Criar uma instância do Axios com rotação
async createAxiosInstance() {
const proxy = this.getActiveProxy();
const agent = new HttpsProxyAgent(proxy.url);
return {
instance: axios.create({
httpsAgent: agent,
timeout: 10000
}),
proxyUrl: proxy.url
};
}
// Obter estatísticas do proxy
getStats() {
return {
total: this.proxyList.length,
active: this.proxyList.filter(p => p.active).length,
inactive: this.proxyList.filter(p => !p.active).length,
proxies: this.proxyList.map(p => ({
url: p.url.replace(/\/\/.*@/, '//***@'), // Ocultar credenciais
active: p.active,
failures: p.failures
}))
};
}
}
// Uso do rotador avançado
const advancedRotator = new AdvancedProxyRotator(proxyList);
async function fetchWithAdvancedRotation(url) {
const { instance, proxyUrl } = await advancedRotator.createAxiosInstance();
try {
const response = await instance.get(url);
advancedRotator.markSuccess(proxyUrl);
return response.data;
} catch (error) {
advancedRotator.markFailure(proxyUrl);
throw error;
}
}
// Relatório periódico de estatísticas
setInterval(() => {
console.log('Estatísticas do proxy:', advancedRotator.getStats());
}, 30000);
Esse sistema exclui automaticamente proxies não funcionais da rotação e distribui uniformemente a carga entre servidores ativos. Isso é crítico ao trabalhar com grandes volumes de dados.
Tratamento de erros e troca automática de proxy
Ao trabalhar com proxies, erros inevitavelmente ocorrem: timeouts, falhas de conexão, bloqueios por parte do servidor de destino. Um tratamento adequado de erros e a troca automática para outro proxy aumentam a confiabilidade da aplicação.
Exemplo de implementação de um sistema com repetições automáticas e troca de proxy:
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
class ResilientProxyClient {
constructor(proxyList, maxRetries = 3) {
this.proxyList = proxyList;
this.maxRetries = maxRetries;
this.currentProxyIndex = 0;
}
// Obter o próximo proxy
getNextProxy() {
const proxy = this.proxyList[this.currentProxyIndex];
this.currentProxyIndex = (this.currentProxyIndex + 1) % this.proxyList.length;
return proxy;
}
// Determinar o tipo de erro
isRetryableError(error) {
// Erros que devem resultar em repetição da solicitação
const retryableCodes = ['ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED'];
const retryableStatuses = [408, 429, 500, 502, 503, 504];
if (error.code && retryableCodes.includes(error.code)) {
return true;
}
if (error.response && retryableStatuses.includes(error.response.status)) {
return true;
}
return false;
}
// Executar solicitação com repetições automáticas
async request(url, options = {}, attempt = 1) {
const proxyUrl = this.getNextProxy();
const agent = new HttpsProxyAgent(proxyUrl);
const config = {
...options,
httpsAgent: agent,
timeout: 10000,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
...options.headers
}
};
try {
console.log(`Tentativa ${attempt}/${this.maxRetries} com proxy: ${proxyUrl.replace(/\/\/.*@/, '//***@')}`);
const response = await axios.get(url, config);
console.log(`Sucesso na tentativa ${attempt}`);
return response.data;
} catch (error) {
console.error(`Tentativa ${attempt} falhou: ${error.message}`);
// Se o limite de repetições foi alcançado
if (attempt >= this.maxRetries) {
console.error(`Máximo de repetições (${this.maxRetries}) alcançado para ${url}`);
throw error;
}
// Se o erro não é recuperável
if (!this.isRetryableError(error)) {
console.error(`Erro não recuperável: ${error.message}`);
throw error;
}
// Atraso exponencial antes da repetição
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
console.log(`Aguardando ${delay}ms antes da repetição...`);
await new Promise(resolve => setTimeout(resolve, delay));
// Repetição recursiva com o próximo proxy
return this.request(url, options, attempt + 1);
}
}
// Processamento em lote de URLs com tratamento de erros
async batchRequest(urls, concurrency = 3) {
const results = [];
const queue = [...urls];
const active = [];
while (queue.length > 0 || active.length > 0) {
// Iniciar novas tarefas até atingir o limite de paralelismo
while (active.length < concurrency && queue.length > 0) {
const url = queue.shift();
const promise = this.request(url)
.then(data => ({ url, success: true, data }))
.catch(error => ({ url, success: false, error: error.message }))
.finally(() => {
const index = active.indexOf(promise);
if (index > -1) active.splice(index, 1);
});
active.push(promise);
}
// Aguardar a conclusão de pelo menos uma tarefa
if (active.length > 0) {
const result = await Promise.race(active);
results.push(result);
}
}
return results;
}
}
// Uso
const proxyList = [
'http://user1:pass1@proxy1.example.com:8080',
'http://user2:pass2@proxy2.example.com:8080',
'http://user3:pass3@proxy3.example.com:8080'
];
const client = new ResilientProxyClient(proxyList, 3);
// Solicitação única
client.request('https://api.example.com/data')
.then(data => console.log('Dados:', data))
.catch(error => console.error('Erro final:', error.message));
// Processamento em lote
const urls = [
'https://api.example.com/data/1',
'https://api.example.com/data/2',
'https://api.example.com/data/3',
'https://api.example.com/data/4',
'https://api.example.com/data/5'
];
client.batchRequest(urls, 3)
.then(results => {
const successful = results.filter(r => r.success).length;
const failed = results.filter(r => !r.success).length;
console.log(`Concluído: ${successful} bem-sucedidos, ${failed} falharam`);
console.log('Resultados:', results);
});
Esta implementação inclui:
- Troca automática para o próximo proxy em caso de erro
- Atraso exponencial entre repetições (1s, 2s, 4s, 8s, 10s max)
- Determinação do tipo de erro para decisão de repetição
- Controle de paralelismo durante o processamento em lote
- Registro detalhado para depuração
Melhores práticas e otimização de desempenho
Ao trabalhar com proxies em aplicações Node.js, é importante seguir as seguintes recomendações para garantir estabilidade e desempenho:
1. Gerenciamento de conexões
Reutilize agentes HTTP em vez de criar novos para cada solicitação. Isso reduz a sobrecarga na criação de conexões:
const { HttpsProxyAgent } = require('https-proxy-agent');
// Ruim: criação de agente para cada solicitação
async function badExample(url) {
const agent = new HttpsProxyAgent(proxyUrl);
return axios.get(url, { httpsAgent: agent });
}
// Bom: reutilização do agente
const agent = new HttpsProxyAgent(proxyUrl);
const axiosInstance = axios.create({
httpsAgent: agent,
httpAgent: agent
});
async function goodExample(url) {
return axiosInstance.get(url);
}
2. Configuração de timeouts
Sempre defina timeouts razoáveis para evitar que a aplicação fique travada:
const axiosInstance = axios.create({
httpsAgent: agent,
timeout: 10000, // Timeout geral
// Configuração detalhada de timeouts para Got
// timeout: {
// lookup: 1000, // Pesquisa DNS
// connect: 2000, // Conexão com o proxy
// secureConnect: 2000, // Handshake SSL
// socket: 5000, // Inatividade do socket
// response: 3000, // Espera pelo primeiro byte da resposta
// send: 10000, // Envio da solicitação
// request: 15000 // Toda a solicitação
// }
});
3. Controle de paralelismo
Limite o número de solicitações simultâneas para evitar sobrecarga:
const pLimit = require('p-limit');
// Limitar a 5 solicitações simultâneas
const limit = pLimit(5);
async function processUrls(urls) {
const promises = urls.map(url =>
limit(() => axiosInstance.get(url))
);
return Promise.allSettled(promises);
}
4. Rotação de User-Agent
Combine a rotação de proxies com a rotação de User-Agent para maior anonimato:
const userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0'
];
function getRandomUserAgent() {
return userAgents[Math.floor(Math.random() * userAgents.length)];
}
async function fetchWithRandomUA(url) {
return axiosInstance.get(url, {
headers: {
'User-Agent': getRandomUserAgent()
}
});
}
5. Monitoramento e registro
Implemente um sistema de monitoramento para rastrear o desempenho dos proxies:
class ProxyMonitor {
constructor() {
this.stats = new Map();
}
recordRequest(proxyUrl, success, responseTime) {
if (!this.stats.has(proxyUrl)) {
this.stats.set(proxyUrl, {
total: 0,
success: 0,
failed: 0,
totalResponseTime: 0,
avgResponseTime: 0
});
}
const stat = this.stats.get(proxyUrl);
stat.total++;
if (success) {
stat.success++;
stat.totalResponseTime += responseTime;
stat.avgResponseTime = stat.totalResponseTime / stat.success;
} else {
stat.failed++;
}
}
getReport() {
const report = [];
this.stats.forEach((stat, proxyUrl) => {
report.push({
proxy: proxyUrl.replace(/\/\/.*@/, '//***@'),
successRate: ((stat.success / stat.total) * 100).toFixed(2) + '%',
avgResponseTime: stat.avgResponseTime.toFixed(0) + 'ms',
total: stat.total,
success: stat.success,
failed: stat.failed
});
});
return report;
}
}
const monitor = new ProxyMonitor();
// Wrapper para solicitações com monitoramento
async function monitoredRequest(url, proxyUrl) {
const startTime = Date.now();
try {
const response = await axiosInstance.get(url);
const responseTime = Date.now() - startTime;
monitor.recordRequest(proxyUrl, true, responseTime);
return response.data;
} catch (error) {
const responseTime = Date.now() - startTime;
monitor.recordRequest(proxyUrl, false, responseTime);
throw error;
}
}
// Relatório periódico
setInterval(() => {
console.table(monitor.getReport());
}, 60000);
6. Escolha do tipo de proxy
Escolha o tipo de proxy com base na tarefa:
| Tarefa | Tipo recomendado | Razão |
|---|---|---|
| Scraping em massa de dados públicos | Proxies de datacenter | Alta velocidade, baixo custo |
| Trabalho com redes sociais e plataformas com proteção | Proxies residenciais | IPs reais, baixo risco de bloqueio |
| Emulação de tráfego móvel | Proxies móveis | IPs de operadoras móveis |
| Trabalho com protocolos não padrão | Proxies SOCKS5 | Suporte a qualquer tráfego |
Para tarefas que exigem um alto nível de anonimato e risco mínimo de bloqueios, recomenda-se usar proxies residenciais. Para scraping em alta velocidade de grandes volumes de dados, proxies de datacenter são adequados.
7. Segurança das credenciais
Nunca armazene credenciais de proxy no código. Use variáveis de ambiente:
// arquivo .env
PROXY_HOST=proxy-server.com
PROXY_PORT=8080
PROXY_USERNAME=your-username
PROXY_PASSWORD=your-password
// No código
require('dotenv').config();
const proxyUrl = `http://${process.env.PROXY_USERNAME}:${process.env.PROXY_PASSWORD}@${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`;
// Ou para a lista de proxies
const proxyList = process.env.PROXY_LIST.split(',').map(proxy => proxy.trim());
Conclusão
A configuração de proxies em aplicações Node.js é uma habilidade importante para desenvolvedores que trabalham com scraping, automação e integração com APIs externas. Neste guia, abordamos todas as principais formas de trabalhar com proxies: desde a configuração básica através de módulos embutidos até técnicas avançadas com rotação, tratamento de erros e monitoramento.
Pontos-chave a serem lembrados:
- Escolha a biblioteca para solicitações HTTP com base na tarefa: Axios para versatilidade, Got para projetos TypeScript, node-fetch para compatibilidade com a API do navegador
- Use proxies SOCKS5 para trabalhar com protocolos não padrão e máxima flexibilidade
- Implemente rotação de proxies para distribuição de carga e evitar bloqueios
- Implemente um sistema de tratamento de erros com repetições automáticas e troca de proxies
- Monitore o desempenho dos proxies e exclua automaticamente os não funcionais
- Reutilize agentes HTTP e configure timeouts razoáveis
- Armazene credenciais em variáveis de ambiente, não no código
Ao escolher proxies para suas aplicações Node.js, considere a especificidade da tarefa. Para scraping de plataformas protegidas e trabalho com APIs sensíveis à reputação do IP, recomendamos o uso de proxies residenciais — eles oferecem um alto nível de anonimato e risco mínimo de bloqueios devido ao uso de endereços IP reais de usuários domésticos.