Jawaban cepat
Bagaimana cara menggunakan proxy bergilir di Node.js?
Dengan fetch, buat undici ProxyAgent untuk http://gw.crawlrelay.com:7777 dan berikan sebagai dispatcher. Dengan axios atau got, berikan agen proxy seperti https-proxy-agent atau hpagent, dan setel proxy: false di axios. Proxy residensialCrawlRelay membaca negara dan sesi dari username, dari US$0,50/GB. Dibayar dengan crypto, tanpa KYC.
Pengaturan Node.js sekilas
| fetch / undici | new ProxyAgent({ uri, token }), lalu fetch(url, { dispatcher }) |
|---|---|
| axios | httpsAgent: new HttpsProxyAgent(url) dan proxy: false |
| got | agent: { https: new HttpsProxyAgent({ proxy }) } dari hpagent |
| SOCKS5 | socks-proxy-agent dengan URL socks5h:// di port 7778 |
| IP baru per permintaan | Agen baru atau session ID baru per permintaan; koneksi pooled mempertahankan exit mereka |
| Format modul | Contoh adalah modul ES (.mjs atau "type": "module") dengan top-level await |
Bagaimana cara menggunakan proxy dengan fetch di Node?
Global fetch Node dibangun di atas undici tapi secara default tidak membaca HTTP_PROXY atau HTTPS_PROXY. Pasang undici dan berikan ProxyAgent sebagai dispatcher. Field token mengirim kredensial sebagai header Proxy-Authorization, sehingga password tidak pernah muncul di URL yang bisa tercatat.
import { ProxyAgent, fetch } from "undici";
const credentials = Buffer.from("USERNAME-country-us:PASSWORD").toString("base64");
const dispatcher = new ProxyAgent({
uri: "http://gw.crawlrelay.com:7777",
token: `Basic ${credentials}`,
});
const res = await fetch("https://api.ipify.org?format=json", {
dispatcher,
signal: AbortSignal.timeout(30000),
});
console.log(res.status, await res.json());
await dispatcher.close();Bagaimana cara menggunakan proxy dengan axios?
Jangan andalkan opsi proxy axios sendiri untuk situs HTTPS: itu mengirimkan permintaan ke proxy tanpa tunnel CONNECT, yang banyak proxy tolak. Nonaktifkan dengan proxy: false dan berikan agent yang membuka tunnel yang benar.
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";
const agent = new HttpsProxyAgent("http://USERNAME-country-de:[email protected]:7777");
const client = axios.create({ httpsAgent: agent, httpAgent: agent, proxy: false, timeout: 30000 });
const { data } = await client.get("https://api.ipify.org?format=json");
console.log(data.ip);Bagaimana cara menggunakan proxy dengan got?
got menggunakan satu agent per protokol. hpagent mengikuti http.Agent Node: keep-alive mati kecuali Anda mengaktifkan keepAlive: true. Biarkan mati, atau setel keepAlive: false seperti di bawah, ketika Anda ingin setiap permintaan menggunakan koneksi baru, dan biasanya exit baru.
import got from "got";
import { HttpsProxyAgent } from "hpagent";
const proxy = "http://USERNAME-country-fr:[email protected]:7777";
const body = await got("https://api.ipify.org", {
agent: { https: new HttpsProxyAgent({ proxy, keepAlive: false }) },
timeout: { request: 30000 },
retry: { limit: 2, statusCodes: [429, 502, 503, 504] },
}).text();
console.log(body);Bagaimana cara menggunakan SOCKS5 di Node.js?
Gunakan socks-proxy-agent dengan skema socks5h:// agar hostname diselesaikan di exit. Ini bekerja dengan modul http dan https Node serta dengan library apa pun yang menerima agent.
import https from "node:https";
import { SocksProxyAgent } from "socks-proxy-agent";
const agent = new SocksProxyAgent("socks5h://USERNAME-country-gb:[email protected]:7778");
const req = https.get("https://api.ipify.org", { agent, timeout: 30000 }, (res) => {
let body = "";
res.on("data", (chunk) => (body += chunk));
res.on("end", () => console.log(res.statusCode, body));
});
req.on("timeout", () => req.destroy(new Error("timeout after 30 s")));
req.on("error", (err) => console.error(err.code, err.message));Bagaimana cara membatasi concurrency per host tanpa library?
Promise.all untuk 10.000 URL membuka 10.000 permintaan sekaligus. Pembatas kecil per hostname menjaga setiap situs tetap sopan sementara crawl berjalan paralel. Versi di bawah tidak tergantung apa pun dan bekerja dengan klien apa pun di atas.
import { ProxyAgent, fetch } from "undici";
const PER_HOST = 4;
const active = new Map();
const waiting = new Map();
const dispatcher = new ProxyAgent("http://USERNAME-country-us:[email protected]:7777");
async function withHostSlot(url, task) {
const host = new URL(url).hostname;
while ((active.get(host) ?? 0) >= PER_HOST) {
await new Promise((resolve) => {
if (!waiting.has(host)) waiting.set(host, []);
waiting.get(host).push(resolve);
});
}
active.set(host, (active.get(host) ?? 0) + 1);
try {
return await task();
} finally {
active.set(host, active.get(host) - 1);
waiting.get(host)?.shift()?.();
}
}
const urls = ["https://example.com/", "https://example.org/", "https://example.net/"];
const results = await Promise.all(
urls.map((url) =>
withHostSlot(url, async () => {
const res = await fetch(url, { dispatcher, signal: AbortSignal.timeout(30000) });
return [url, res.status, (await res.arrayBuffer()).byteLength];
}).catch((err) => [url, err.name, 0])
)
);
console.table(results);
await dispatcher.close();Mengapa saya mendapatkan IP yang sama dua kali, atau ECONNRESET?
Agent mengelola koneksi pool, dan koneksi pooled mempertahankan exit saat dibuka. Untuk IP baru tiap permintaan, buat agent baru per permintaan dan tutup setelahnya, matikan keep-alive di agent, atau beri -session-<id> unik di username tiap permintaan.
ECONNRESET dan socket hang up biasanya berasal dari penggunaan ulang socket pooled yang sudah ditutup oleh sisi lain, atau dari exit yang drop. Coba ulang permintaan GET sekali dengan koneksi baru. Halaman connection reset membahas detailnya.
Node.js dan proxy: pertanyaan
Apakah fetch Node.js mendukung HTTP_PROXY?
Tidak secara default di versi yang kebanyakan proyek pakai saat ini: fetch global mengabaikan variabel lingkungan proxy kecuali Anda memberi dispatcher. Gunakan undici ProxyAgent seperti contoh di atas, atau atur dispatcher global dengan undici setGlobalDispatcher() jika semua permintaan dalam proses harus lewat proxy.
Kenapa axios gagal dengan situs HTTPS di belakang proxy?
Opsi proxy bawaan axios mengirim permintaan HTTPS ke proxy dengan cara yang banyak proxy tolak, bukannya membuka tunnel CONNECT. Aktifkan proxy: false dan berikan HttpsProxyAgent sebagai httpsAgent. Permintaan kemudian lewat tunnel yang benar, dan TLS tetap antara kode Anda dan situs.
Bagaimana mengirim request dari berbagai negara dalam satu proses Node.js?
Buat satu agent per negara, tiap agent dengan username sendiri seperti USERNAME-country-de atau USERNAME-country-jp, dan pilih agent per permintaan. Agent murah, dan memisahkan mereka juga memisahkan kumpulan koneksinya, serta exit-nya.
Timeout mana yang harus saya setel di Node.js?
Selalu setel: AbortSignal.timeout(30000) untuk fetch, timeout: 30000 untuk axios, timeout: { request: 30000 } untuk got. Tiga puluh detik cocok untuk halaman HTML; berikan target lambat dan exit seluler hingga 60 detik, dan lakukan retry sekali dengan koneksi baru daripada menunggu lebih lama.
Hubungkan crawler Node.js Anda
US$5,94 untuk 10 GB, US$0,50/GB dari 50 GB.